You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CryptoJS加密内容无法用PHP OpenSSL解密:密钥生成问题咨询

问题分析与解决方案

你的问题出在两个核心细节上,导致PHP生成的密钥和JS端不匹配,进而无法解密:

1. PBKDF2哈希算法不一致

CryptoJS 的 PBKDF2 方法默认使用 SHA-1 作为哈希函数,但你的PHP代码里错误指定了 'sha256'。算法不一样,生成的密钥自然完全不同,这是最关键的问题。

2. 密钥格式处理错误

PHP的openssl_pbkdf2函数直接返回原始二进制密钥,但你用bin2hex()把它转换成了十六进制字符串。而openssl_decrypt需要的是二进制格式的密钥,不是十六进制形式——这也是为什么你直接用JS控制台输出的密钥能解密的原因:你相当于跳过了错误的格式转换,直接用了匹配的十六进制密钥。


修正后的PHP代码

$text_key = 'thepassword';
$cipher = "aes-256-cbc";
$received_message = $_REQUEST['message'];

// 解码消息并直接按二进制截取各部分(无需转十六进制,更高效)
$decoded = base64_decode($received_message);
$salt = substr($decoded, 0, 32);    // 256位盐 = 32字节
$iv = substr($decoded, 32, 16);     // 128位IV = 16字节
$encrypted_data = substr($decoded, 48); // 剩余部分是加密后的二进制数据

// 生成密钥:使用SHA-1(和CryptoJS默认一致),保留原始二进制格式
$generated_key = openssl_pbkdf2($text_key, $salt, 32, 100, 'sha1');

// 解密:传入二进制加密数据、二进制密钥、二进制IV
$result = openssl_decrypt($encrypted_data, $cipher, $generated_key, OPENSSL_RAW_DATA, $iv);

echo $result; // 此时应该输出 "This is my test"

额外优化提示

  • 你原本把base64解码后的二进制转成十六进制再截取的操作完全没必要,直接按字节长度截取二进制数据更高效,还能避免转换过程中可能出现的错误。
  • 如果后续想统一使用SHA-256提升安全性,需要同时修改JS代码,在PBKDF2的配置中添加hash: CryptoJS.SHA256,确保两端算法完全一致。

内容的提问来源于stack exchange,提问作者zeddy218

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:29:39