求助:无法用CryptoJS复现Java的AES-CBC加密解密
跨平台AES-CBC加密互通问题解决(CryptoJS ↔ Java)
需求说明
- 目标:使用CryptoJS复现Java的AES-CBC加密/解密逻辑
- 目的:实现跨平台密文互通,让CryptoJS生成的Base64/HEX密文可在Java环境解密
- 问题:当前两端生成的密文不一致,导致跨平台解密失败
输出对比
Java代码输出
SECRET_KEY: 431.396 SALT: d413321c765f563c8288ce281ae6808d originalString: test123_XXX encryptedString: suBMmUzhQMtuAboORtvr6g== encryptedStringHex: 7375424d6d557a68514d747541626f4f5274767236673d3d decryptedString: test123_XXX
原JavaScript代码输出
[Log] SECRET_KEY: 431.396 [Log] SALT: d413321c765f563c8288ce281ae6808d [Log] originalString: test123_XXX [Log] Encrypted: l+R6aYgrQI2+RAIH+X/iJw== [Log] encryptedHex: 97E47A69882B408DBE440207F97FE227 [Log] Decrypted: test123_XXX
问题根源
两端加密逻辑存在两处关键差异:
- PBKDF2哈希算法不匹配:Java使用
PBKDF2WithHmacSHA256,而CryptoJS的PBKDF2默认采用SHA1,原JS代码未指定哈希算法 - IV长度不匹配:Java使用16字节全0向量,原JS代码仅生成8字节IV(Hex解析16个字符对应8字节)
修正后的JavaScript代码
var SECRET_KEY = "431.396"; var SALT = "d413321c765f563c8288ce281ae6808d"; var originalString = "test123_XXX"; // 生成16字节全0IV,与Java一致(32个十六进制0对应16字节) var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000'); var iterations = 65536; var keySize = 256; function encrypt(msg) { var key = CryptoJS.PBKDF2(SECRET_KEY, SALT, { keySize: keySize / 32, iterations: iterations, hasher: CryptoJS.algo.SHA256 // 对齐Java的PBKDF2WithHmacSHA256 }); var encrypted = CryptoJS.AES.encrypt(msg, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }); return encrypted; } function decrypt(encrypted) { var key = CryptoJS.PBKDF2(SECRET_KEY, SALT, { keySize: keySize / 32, iterations: iterations, hasher: CryptoJS.algo.SHA256 }); var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }); return decrypted; } var encrypted = encrypt(originalString); var encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex); var decrypted = decrypt(encrypted); console.log("SECRET_KEY: " + SECRET_KEY); console.log("SALT: " + SALT); console.log("originalString: " + originalString); console.log("Encrypted: " + encrypted.toString()); // 输出Base64密文,与Java一致 console.log("encryptedHex: " + encryptedHex); console.log("Decrypted: " + decrypted.toString(CryptoJS.enc.Utf8));
修正后JS输出
SECRET_KEY: 431.396 SALT: d413321c765f563c8288ce281ae6808d originalString: test123_XXX Encrypted: suBMmUzhQMtuAboORtvr6g== encryptedHex: 7375424d6d557a68514d747541626f4f5274767236673d3d Decrypted: test123_XXX
验证说明
修正后的JS代码生成的Base64密文和Hex编码与Java完全一致,可直接在Java环境中解密,实现跨平台加密互通。
内容的提问来源于stack exchange,提问作者DavidDunham
相关产品推荐
相关产品推荐

