如何用PHP解密Node.js加密的AES-256-CTR字符串?
解决方案
问题根源在于Node.js的createCipher/createDecipher是已废弃的旧API,它们会通过OpenSSL的EVP_BytesToKey函数,以MD5为哈希算法、无盐、迭代1次的方式,从传入的密码生成密钥和IV,而非直接使用密码作为密钥。PHP的openssl_decrypt默认不会执行这个派生逻辑,因此需要手动复刻。
调整后的PHP解密代码如下:
function decrypt($text, $algorithm, $password) { // 模拟Node.js旧API的密钥与IV生成逻辑 $md5Hash = md5($password, true); // 获取密码的二进制MD5哈希 $iv = substr($md5Hash, 0, 8); // CTR模式下,旧API取MD5哈希前8字节作为IV // 生成AES-256所需的32字节密钥:拼接两次MD5哈希后取前32字节 $key = substr($md5Hash . md5($password, true), 0, 32); // 执行解密:指定CTR模式、传入生成的IV、禁用填充 return openssl_decrypt( hex2bin($text), $algorithm, $key, OPENSSL_NO_PADDING, $iv ); }
关键细节
- 必须严格复刻Node.js旧API的密钥/IV生成规则,否则CTR模式的解密会完全错误
- 保持
OPENSSL_NO_PADDING参数,与Node端的setAutoPadding(false)行为一致 - 两次MD5哈希拼接后正好是32字节,刚好满足AES-256的密钥长度要求
内容的提问来源于stack exchange,提问作者FrancescoPenasa
相关产品推荐
相关产品推荐

