使用CryptoJS解密PHP生成的AES CTR 128密文报错求助
问题根因
你的代码解密失败是三个逻辑错误共同导致的:
- 未接收
CryptoJS.AES.decrypt()的返回值,直接使用未声明的decrypted变量,这是控制台抛出引用错误的直接原因 - 直接向CryptoJS传入字符串格式的密钥和IV,CryptoJS会默认将传入的字符串当作用户密码,通过EVP_BytesToKey算法派生加密密钥,和PHP端
openssl_encrypt直接使用原始字符串作为AES密钥/IV的逻辑完全不匹配,就算解决变量问题也只会解出乱码 - 未显式指定填充规则:AES-CTR属于流加密模式,不需要块填充,CryptoJS默认使用PKCS7填充,和PHP端CTR模式的默认填充逻辑不一致,容易导致解密结果末尾出现乱码
修复后的解密代码
先确保页面中正确引入CryptoJS库,再使用以下代码即可完成解密:
const message = "DEnw6dO5nEZ4k532f3I8U6Vy1m/kgeqZhPAUqjVwCDwBRTUcxkgSn95ROXdy3lPF7ybbIiDIUYtmfru6AaNvUlP9HxOdlMkjSJDMDz7pcDj+Hqioipp/hqfSqPfSkFI8Q+VkBV9b2zNy9lamy4NmaFBo03KvVm3Hw2cMWHeRgE8DTJYPoYrBqIlKJ3PT7E3edd433UGRC/wdZ1jkf1cgpD3HdMHDDRtLnA2q/mbmuYHs7hZSz+CLzBHP6iq4+jEO/6FrLCQSPXqEwyRvTQ73ngS1KOoI5LdhQV7s7vrKJcxHWEBX5A84F7VRo+at/0aE0m71GwmHvJSs5ZrLCkuiLKHqyzO4SUHNeP0f1VqQmuphC0o8M912xfquBI9tv0TIipbvw2hNKKL66tYCBSx8W0C6rodJ+yirHs+Q5CorBqzrYr28it3gqs0bHrkN7A==" // 将字符串格式的key、iv解析为CryptoJS可识别的WordArray格式 const key = CryptoJS.enc.Utf8.parse("AJ89HFJHAJ89HFJH") const iv = CryptoJS.enc.Utf8.parse("hsjsjdkdueooqpjj") // 接收解密返回值,显式指定CTR模式、无填充 const decrypted = CryptoJS.AES.decrypt(message, key, { iv: iv, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding }) // 转换为UTF8明文输出 console.log("Here is decrypted", decrypted.toString(CryptoJS.enc.Utf8))
PHP端配置校验
如果运行上述代码仍然得到乱码,请检查PHP端加密配置:
- 加密算法参数必须设置为
aes-128-ctr,不要错写成aes-256-ctr或其他CBC/ECB变体 openssl_encrypt的options参数如果使用默认值0,输出的密文就是当前代码可直接处理的Base64格式;如果设置了OPENSSL_RAW_DATA,需要先将密文从Base64格式解析为WordArray再传入解密方法- 密钥长度必须为16字节、IV长度必须为16字节,你当前提供的key、iv都是16位ASCII字符,符合AES-128的参数要求
内容的提问来源于stack exchange,提问作者Jasham
相关产品推荐
相关产品推荐

