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

使用openssl_decrypt解密AES-128-GCM加密文件时密钥长度错误问题

问题解决:AES-128-GCM密钥长度不匹配问题

问题根源

你在使用openssl_private_decrypt时指定了OPENSSL_NO_PADDING参数,导致解密结果是包含RSA填充的完整256字节加密块,而非实际的16字节(128位)AES密钥,这直接触发了openssl_decrypt的密钥长度校验错误。

解决方案

方案1:移除手动指定的NO_PADDING参数(优先推荐)

AS4协议中,密钥加密通常遵循PKCS#1 v1.5规范,OpenSSL默认会自动处理这种填充。修改解密密钥的代码:

// 原代码
// openssl_private_decrypt($base64DecodedCipherValue,$decryptedKey, $privateKey, OPENSSL_NO_PADDING);
// 修改后
openssl_private_decrypt($base64DecodedCipherValue, $decryptedKey, $privateKey);

修改后$decryptedKey会自动提取出16字节的AES-128密钥,满足aes-128-gcm的要求。可以添加以下代码验证密钥长度:

var_dump(strlen($decryptedKey)); // 应输出int(16)

方案2:若供应商使用OAEP填充

如果方案1无效,说明供应商可能采用了RSA-OAEP填充,需指定对应的填充参数:

openssl_private_decrypt($base64DecodedCipherValue, $decryptedKey, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);

方案3:手动从现有解密结果中提取密钥(测试用)

针对你提供的$decryptedKeyHex,可以手动提取实际AES密钥:
从十六进制字符串中找到第二个00分隔符,之后的16字节即为目标密钥:

$decryptedKey = hex2bin($decryptedKeyHex);
// 定位第二个0x00字节的位置
$delimiterPos = strpos($decryptedKey, "\x00", 1);
// 提取16字节AES密钥
$aesKey = substr($decryptedKey, $delimiterPos + 1, 16);

// 后续解密使用$aesKey替代$decryptedKey
$decryptedData = openssl_decrypt(
    $ciphertext_raw,
    $cipher,
    $aesKey,
    OPENSSL_RAW_DATA,
    $iv,
    $tag
);

额外验证

确保$binaryData的处理逻辑正确:

  • AES-GCM的IV长度固定为12字节,openssl_cipher_iv_length('aes-128-gcm')会返回12,你的IV提取逻辑是正确的
  • Tag长度为16字节,密文部分的截取逻辑也符合规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:35:01