如何用JavaScript解密PHP中openssl DES-EDE3加密的字符串?
解决CryptoJS解密PHP openssl_encrypt生成的DES-EDE3密文问题
你踩的坑其实很常见:DES-EDE3就是我们常说的Triple DES(3DES)算法,而CryptoJS里对应的实现是CryptoJS.TripleDES,不是你用的CryptoJS.DES——这就是解密失败的核心原因。下面我帮你梳理清楚两边的参数对齐问题,再给你修正后的代码。
先拆解你的PHP加密逻辑
你的PHP代码里几个关键参数需要和JS端完全匹配:
- 算法:
DES-EDE3→ 对应3DES的ECB模式(因为你没有传入IV参数,openssl_encrypt默认使用ECB模式) - 输出格式:
OPENSSL_RAW_DATA→ 加密后直接输出原始二进制,再通过base64_encode转成Base64字符串 - 编码处理:
utf8_encode($pure_string)→ 这里要注意,PHP的utf8_encode是把ISO-8859-1编码转成UTF-8,如果你的原始字符串本身就是UTF-8,这一步反而会导致乱码,后续解密时要对应这个处理。
修正后的CryptoJS解密代码
把CryptoJS.DES换成CryptoJS.TripleDES,同时确保填充、模式和PHP端一致:
// 确保secretkey和PHP端的$encryption_key完全相同 var keyHex = CryptoJS.enc.Utf8.parse(secretkey); // 解析Base64格式的密文 var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Base64.parse(secretText) }); // 使用TripleDES(对应DES-EDE3)解密,ECB模式+PKCS#7填充(和PHP默认一致) var decrypted = CryptoJS.TripleDES.decrypt(cipherParams, keyHex, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); // 转换为UTF-8明文 var plaintext = decrypted.toString(CryptoJS.enc.Utf8); console.info('解密结果:', plaintext);
额外注意事项
- 密钥长度对齐:3DES的标准密钥长度是24字节,如果你的密钥不足24字节,PHP会自动重复密钥填充到24字节,CryptoJS的TripleDES也会做同样的处理,所以务必保证两边密钥完全一致。
- 填充方式:PHP的
openssl_encrypt默认使用PKCS#7填充,CryptoJS的TripleDES默认也是这个填充方式,所以不需要额外修改,但如果PHP端手动指定了其他填充,JS端也要对应调整。 - 编码问题:如果你的原始字符串
$pure_string本身就是UTF-8编码,建议去掉PHP里的utf8_encode,否则会导致解密后的字符串出现乱码(因为utf8_encode只处理ISO-8859-1)。
内容的提问来源于stack exchange,提问作者user2653710
相关产品推荐
相关产品推荐

