You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java AES-256-CBC加密后Node.js解密报错:wrong final block length

Java AES-256-CBC加密后Node.js解密报错:wrong final block length

问题场景

使用Java实现AES-256-CBC加密字符串,再通过Node.js的crypto库解密时,抛出错误:

error:1C80006B:Provider routines::wrong final block length

Java加密代码

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import java.net.URLEncoder;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class TestEncrypt {
    public static String encrypt(String strToEncrypt, String key, byte[] initialVector,String salt) throws Exception{
        IvParameterSpec ivspec = new IvParameterSpec(initialVector);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(key.toCharArray(), salt.getBytes(), 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
    
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
        return URLEncoder.encode(Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8.toString());
    }
    
    public static byte[] decodeToBase64(String base64Value) {
        return Base64.getDecoder().decode(base64Value);
    }
    
    public static String encryptData(String StringToEncode, String base256Key, String base256Iv, String salt) throws Exception {
        String encryptedString = encrypt(StringToEncode, base256Key, decodeToBase64(base256Iv), salt);
        return encryptedString;
    }
    
    public static void main(String args[]) throws Exception {
        String originalValue = "hello world";
        String encryptedValue = encryptData(originalValue, "TSP88GUiIrX5ZyBWAkvWk7JUMBaSlkVADhEB6gsGS9s=", "ZUCKXBlZT6/SdBxLoEJl0Q==", "ssshhhhhhhhhhh!!!!");
        System.out.println("originalValue=" + originalValue);
        System.out.println("encryptedValue=" + encryptedValue);
    }
}

Node.js原解密代码

const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const digest = 'sha256';

function decrypt(strToDecrypt, secretKey, salt, initialVector) {
    const key = crypto.pbkdf2Sync(
        secretKey,
        Buffer.from(salt),
        65536,
        32,
        digest
        );
    const iv = Buffer.from(initialVector, 'base64');

    const decipher = crypto.createDecipheriv(algorithm, key, iv);
    let decrypted = decipher.update(strToDecrypt, 'base64');
    decrypted += decipher.final();
    return decrypted;
}

decrypt('V7qjZNuL%2FKBWRWc3hx1wRw%3D%3D', 'TSP88GUiIrX5ZyBWAkvWk7JUMBaSlkVADhEB6gsGS9s=', 'ssshhhhhhhhhhh!!!!', 'ZUCKXBlZT6/SdBxLoEJl0Q==');

错误原因

Java代码中,加密后的Base64字符串被做了URL编码(URLEncoder.encode),但Node.js解密时直接使用了URL编码后的字符串(比如V7qjZNuL%2FKBWRWc3hx1wRw%3D%3D)进行Base64解码,而%2F、%3D这类URL转义字符不属于合法的Base64字符,导致解密时无法正确解析加密数据,最终抛出块长度错误。

修复后的Node.js解密代码

先对输入的加密字符串做URL解码,再进行解密:

const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const digest = 'sha256';

function decrypt(strToDecrypt, secretKey, salt, initialVector) {
    // 先做URL解码,还原原始Base64字符串
    const decodedStr = decodeURIComponent(strToDecrypt);
    
    const key = crypto.pbkdf2Sync(
        secretKey,
        Buffer.from(salt),
        65536,
        32,
        digest
        );
    const iv = Buffer.from(initialVector, 'base64');

    const decipher = crypto.createDecipheriv(algorithm, key, iv);
    let decrypted = decipher.update(decodedStr, 'base64');
    decrypted += decipher.final();
    return decrypted;
}

// 调用示例
const result = decrypt('V7qjZNuL%2FKBWRWc3hx1wRw%3D%3D', 'TSP88GUiIrX5ZyBWAkvWk7JUMBaSlkVADhEB6gsGS9s=', 'ssshhhhhhhhhhh!!!!', 'ZUCKXBlZT6/SdBxLoEJl0Q==');
console.log(result); // 输出: hello world

内容的提问来源于stack exchange,提问作者williamlee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:05:04