使用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
相关产品推荐
相关产品推荐

