php加密后js无法正确解密,绝大多数情况是iv、密钥处理或编码格式不一致导致的,不是算法本身不可行;php必须用openssl_encrypt(mcrypt已移除),$options设为true返回二进制,iv需严格16字节,密钥建议用hash('sha256',$password,true)生成32字节,js端须用cryptojs.enc.base64.parse()解析php下发的base64密钥和iv,并显式指定cryptojs.pad.pkcs7填充,传输时需base64_encode后再urlencode,js端按序atob→parse→decrypt。

PHP 加密后 JS 无法正确解密,绝大多数情况是 IV、密钥处理或编码格式不一致导致的,不是算法本身不可行。
PHP 端必须用 openssl_encrypt 而非 mcrypt_encrypt
PHP 7.1+ 已彻底移除 mcrypt 扩展,硬切回 mcrypt_encrypt 会直接报错或返回空。即使兼容层存在,行为也不稳定。
-
openssl_encrypt的第 4 个参数($options)必须设为true才返回原始二进制数据,否则返回 base64 编码字符串 —— 这和前端CryptoJS.AES.encrypt默认返回 base64 的行为不匹配,容易漏掉一层 decode - IV 长度必须严格为 16 字节(AES-CBC 要求),
substr($key, 0, 16)这类取法风险极高:如果原始密钥不足 16 字节,substr会截出空字符串或短字节,导致 PHP 解密失败但不报错 - 密钥建议用
hash('sha256', $password, true)生成 32 字节密钥(适配 AES-256),避免手动截取出错
JS 端 IV 和密钥必须与 PHP 完全一致且类型正确
CryptoJS 所有输入都要求是 CryptoJS.enc.Utf8.parse() 或 CryptoJS.enc.Hex.parse() 后的对象,不能直接传字符串或 base64。
- PHP 生成的 IV 必须以十六进制或 base64 形式传给 JS,JS 再用
CryptoJS.enc.Hex.parse()或CryptoJS.enc.Base64.parse()转成字节数组;直接parse('1234567890123456')是错的 —— 它把字符串当 UTF-8 解析,不是原始字节 - 密钥同理:PHP 用
hash('sha256', $pwd, true)得到二进制密钥,JS 必须用CryptoJS.enc.Base64.parse(btoa(String.fromCharCode(...)))或更稳妥地,让 PHP 把密钥也 base64 输出,JS 用CryptoJS.enc.Base64.parse()解析 - padding 必须显式指定为
CryptoJS.pad.Pkcs7,否则默认用 ZeroPadding,和 PHP 的 PKCS#7 不兼容
传输时注意 base64 和 URL 安全性问题
加密结果本质是二进制,直接拼进 URL 或 POST body 易被截断或转义损坏。
- PHP 加密后,用
base64_encode()包一层再传,JS 收到后先atob()解码,再交给CryptoJS.enc.Base64.parse()—— 注意顺序:不是所有 base64 字符串都能直接喂给CryptoJS.AES.decrypt - 若需 URL 传递,PHP 端用
urlencode(),JS 端用decodeURIComponent(),别混用escape/unescape(已废弃) - 不要在 JS 里对加密结果再调
encodeURIComponent—— 如果 PHP 已做过urlencode,重复编码会导致 + 号变空格、/ 变 %2F,解密失败
最易忽略的是:PHP 和 JS 对“同一个密钥字符串”生成的二进制密钥完全不同。PHP 的 hash('sha256', $str, true) 和 JS 的 CryptoJS.SHA256($str).toString(CryptoJS.enc.Base64) 输出不同,必须统一用 PHP 生成并下发密钥和 IV 的 base64 表示,JS 仅负责解析使用,不自行计算。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











