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

使用OpenSSL无法正确解密AES-256-CBC加密数据问题求助

解决OpenSSL解密报错:error:0606508A:digital envelope routines:EVP_DecryptFinal_ex:data not multiple of block length

我之前也碰到过这个报错,核心原因其实很明确:你用的填充规则和第三方加密时用的不匹配,导致解密时数据长度不符合AES-CBC的块大小要求(AES块固定是16字节)。

问题出在哪?

你代码里指定了OPENSSL_ZERO_PADDING(零填充),但能在线解密成功,说明第三方加密时用的是行业通用的PKCS#7(或PKCS#5)填充,这两种填充逻辑完全不一样:

  • PKCS#7填充:如果数据不够16字节,就填充n个值为n的字节(比如缺3字节就填3个0x03);要是刚好凑够16字节倍数,还会额外填16个0x10,方便解密时识别并移除填充内容。
  • 零填充:只填0字节,这种方式几乎没人用,还容易和原始数据末尾的0混淆。

用零填充去解PKCS#7填充的加密数据,自然会触发“数据不是块长度倍数”的报错。

修复代码很简单

把OPENSSL_ZERO_PADDING换成OPENSSL_RAW_DATA(或者直接省略这个参数,因为openssl_decrypt默认就是自动处理PKCS填充的),同时保证密钥和IV的十六进制转二进制是对的:

$result = openssl_decrypt(
    $bin,
    'AES-256-CBC',
    hex2bin($this->key),
    OPENSSL_RAW_DATA, // 自动识别并移除PKCS填充
    hex2bin($this->iv)
);

if (!$result) {
    while ($msg = openssl_error_string()) {
        echo "ERROR: " . $msg;
    }
}

额外要检查的几个点

  • 确认$bin是纯二进制的加密数据,没有被Base64之类的编码过——如果是Base64格式的,得先base64_decode($bin)再解密。
  • 核对密钥和IV的长度:AES-256的密钥必须是32字节(对应64位十六进制字符串),IV必须是16字节(对应32位十六进制字符串),长度不对的话解密肯定失败。
  • 可以先打印strlen($bin)看看是不是16的整数倍,如果不是,那大概率是加密数据在传输过程中被截断或者编码出错了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:35:20