Angular使用CryptoJS与Java AES加解密结果不一致的问题及修复方案
问题根因
- 密钥处理逻辑不匹配:Java端先对传入的原始密钥做SHA-1哈希运算,再截取哈希结果的前16字节作为实际AES加密密钥;Angular端直接将原始密钥字符串转UTF-8字节作为密钥,二者实际使用的密钥完全不同,这是加密结果不一致的核心原因。
- 冗余IV参数:AES的ECB模式不需要初始化向量(IV),Angular代码中传入IV参数属于冗余配置,虽然ECB模式下CryptoJS会自动忽略IV参数,但属于不规范写法。
- keySize参数多余:AES密钥长度由传入的密钥字节长度决定,16字节对应AES-128,不需要额外配置keySize参数。
修复方案
以下是和Java端逻辑完全对齐的Angular端加解密代码,可实现双向互通:
import * as CryptoJS from 'crypto-js'; // 加密方法 encrypt(plainText: string, secret: string): string { // 1. 对原始密钥做SHA-1哈希,对齐Java端setKey逻辑 const sha1Hash = CryptoJS.SHA1(secret); // 2. 取SHA-1结果前16字节作为AES实际密钥(1个word对应4字节,取前4个word即16字节) const aesKey = CryptoJS.lib.WordArray.create(sha1Hash.words.slice(0, 4)); // 3. 加密配置:ECB模式、Pkcs7填充(和Java端PKCS5Padding完全兼容) const encrypted = CryptoJS.AES.encrypt(plainText, aesKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); // 返回Base64格式加密结果,和Java端输出格式对齐 return encrypted.toString(); } // 解密方法 decrypt(cipherText: string, secret: string): string { const sha1Hash = CryptoJS.SHA1(secret); const aesKey = CryptoJS.lib.WordArray.create(sha1Hash.words.slice(0, 4)); const decrypted = CryptoJS.AES.decrypt(cipherText, aesKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); // 转UTF-8明文返回 return decrypted.toString(CryptoJS.enc.Utf8); } // 测试用例 public message: string= "{\"title\": \"TestTitle1\",\"author\": \"TestAuthor1\"}"; public password: string ="Thisisatestkeyfortesting"; test() { const encryptedStr = this.encrypt(this.message, this.password); // 输出结果和Java端完全一致:Qua63XoZnGDpvBYtmoEZipALDamRw6EvmB0oWLD+wgi80PzmMZw2WTX4CIP6R79+ console.log('加密结果:', encryptedStr); const decryptedStr = this.decrypt(encryptedStr, this.password); // 输出原始明文:{"title": "TestTitle1","author": "TestAuthor1"} console.log('解密结果:', decryptedStr); }
注意:现有逻辑使用的AES/ECB模式安全性较低,若后续迭代可调整Java端逻辑,建议替换为CBC模式并配置随机IV,提升加密安全性。
内容的提问来源于stack exchange,提问作者Kris Swat
相关产品推荐
相关产品推荐

