
cryptojs aes加密后返回base64字符串,但解密后直接调用`.tostring()`会默认输出十六进制编码(如”6869″),需显式指定`cryptojs.enc.utf8`才能正确还原原始字符串。
在使用 CryptoJS 进行 AES 加密/解密时,一个常见误区是忽略了 加密输出 与 解密输出 的编码处理方式。你观察到 encrypt(“hi”, “12345”) 返回类似 U2FsdGVkX1++p462vXg3LggRE5kzRtX3VbKkcMBWuHY= 的 Base64 字符串,这是正确的;但当你对返回值直接调用 decrypt(…).toString() 时,CryptoJS 默认将其转为十六进制字符串(”6869″ 即 “h” 和 “i” 的 ASCII 十六进制表示),而非原始 UTF-8 文本。
根本原因在于:
- CryptoJS.AES.encrypt() 返回的是一个 CipherParams 对象(非纯字符串),其 .toString() 方法默认使用 CryptoJS.enc.Hex 编码;
- CryptoJS.AES.decrypt() 返回的是 wordArray 对象,必须通过 .toString(CryptoJS.enc.Utf8) 显式解码为可读字符串。
✅ 正确用法如下:
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 密钥安全性:”12345″ 是弱口令,实际项目中应使用强随机密钥(如 CryptoJS.lib.WordArray.random(256/8))或派生密钥(PBKDF2);
- 版本兼容性:示例使用 CryptoJS v3.1.2,新版(v4+)API 有差异(如需显式传入 { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
- 跨平台一致性:若需与后端(如 node.js crypto 模块)互通,务必统一:密钥派生方式、IV(初始化向量)、填充模式(默认 PKCS7)、编码格式(Base64);
- 避免明文密钥硬编码:前端密钥易被逆向,敏感场景建议仅用于临时混淆,勿替代服务端加密。
总结:CryptoJS 的 .toString() 行为取决于上下文对象类型和编码参数——加密结果调用 .toString() 得 Base64;解密结果必须显式传入 CryptoJS.enc.Utf8 才能获得预期明文。掌握这一细节,即可稳定实现前后端兼容的 AES 字符串加解密。