CryptoJS解密URL传递的AES加密参数失效问题排查
问题原因
CryptoJS.AES.encrypt() 返回值不是原生字符串,是携带加密元数据的 CipherParams 对象。本地直接运行能解密成功,是因为把该对象直接传入 decrypt 方法时,CryptoJS 可自动识别对象结构完成解密。
通过URL传参、或硬编码字符串形式的加密值时,传入decrypt的是纯字符串,会触发两个常见问题:
- URL传输过程中,加密串包含的
+、/、=等特殊字符会被URL编码规则转义,直接使用转义后的串解密无法得到正确结果 - 即使硬编码复制控制台打印的加密串,只要传入的是纯字符串格式,CryptoJS会默认按OpenSSL兼容格式解析,一旦字符串在复制、传输过程中出现字符丢失、格式偏移,就会解密得到空值
修正方法
- 加密端先输出标准字符串格式的加密结果,再做URL安全编码后再放入URL参数:
// 加密端逻辑 var request = "testing decryption"; // 显式将加密结果转为字符串 var encryptedStr = CryptoJS.AES.encrypt(request, 'somekey').toString(); // 做URL编码,避免特殊字符在传输中被转义 const urlSafeValue = encodeURIComponent(encryptedStr); // 后续将urlSafeValue拼接进URL传递
- 解密端拿到URL参数后,先做URL解码,再执行解密操作:
// 解密端逻辑 // 取出URL参数后先做URL解码 var user_details = decodeURIComponent(this.props.match.params.userdetails); var decryptedRequest = CryptoJS.AES.decrypt(user_details, 'somekey'); var decryptedMessage = decryptedRequest.toString(CryptoJS.enc.Utf8) console.log('Decrypted Request: ' + decryptedMessage);
排查提示:如果修正后仍有问题,可以在解密端打印拿到的加密串,和本地加密后toString()输出的原始串逐字符对比,只要存在字符不一致(比如
+被转成空格、末尾的=被截断),就说明传输过程中仍存在编码问题。
内容的提问来源于stack exchange,提问作者Sucheta Singha
相关产品推荐
相关产品推荐

