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

PHP使用openssl_decrypt解密乱码 openssl_random_pseudo_bytes相关问题

问题根本原因

AES-128-CBC属于分组密码的CBC模式,加密和解密必须使用完全相同的IV(初始化向量)才能得到正确结果。你当前的代码里加密时随机生成了一个IV,解密时又重新生成了另一个完全无关的随机IV,两个IV不匹配才是解密乱码的核心原因,和openssl_random_pseudo_bytes本身的用法、IV长度设置都没有关系,就算你替换成动态计算IV长度的写法也解决不了问题。

修复方案

核心逻辑是把加密时生成的IV和密文绑定在一起存储/传输,IV本身不需要保密,直接明文拼接在密文前即可,解密时先从密文里拆分出IV再解密即可。

修正后的代码示例

function aes_encode($text, $s_key){
    $iv_length = openssl_cipher_iv_length("AES-128-CBC");
    $iv = openssl_random_pseudo_bytes($iv_length);
    // 执行加密
    $encrypted = openssl_encrypt($text, "AES-128-CBC", $s_key, 0, $iv);
    // 把IV拼在加密结果前面,再统一做base64编码
    return base64_encode($iv . $encrypted);
}

function aes_decode($encrypt_text, $s_key){
    $decoded = base64_decode($encrypt_text);
    $iv_length = openssl_cipher_iv_length("AES-128-CBC");
    // 从解码后的内容前N位拆分出IV,剩余部分为实际密文
    $iv = substr($decoded, 0, $iv_length);
    $encrypted = substr($decoded, $iv_length);
    // 用加密时对应的IV解密
    return openssl_decrypt($encrypted, "AES-128-CBC", $s_key, 0, $iv);
}

// 测试用例
$plaintext = "测试明文";
$s_key = "1234567890123456"; // 注意AES-128要求密钥必须为16字节长度,长度不符合也会导致解密异常
$encrypt_text = aes_encode($plaintext, $s_key);
echo $encrypt_text . PHP_EOL;
$decrypt_text = aes_decode($encrypt_text, $s_key);
echo $decrypt_text . PHP_EOL;
额外注意事项
  • 密钥长度必须和选用的加密算法匹配:AES-128要求密钥长度16字节、AES-192要求24字节、AES-256要求32字节,长度不符合时PHP底层会自动截断/补全,不同版本行为不一致易导致解密失败
  • openssl_encrypt和openssl_decrypt的第四个参数(options参数)两端必须保持一致,你当前使用的0是正确配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:57:00