PHP 8.0.8下openssl_seal加密后openssl_open解密返回FALSE问题排查
问题根因
你使用的aes-256-gcm属于AEAD(带认证的加密)类算法,PHP的openssl_seal、openssl_open处理这类算法时,必须配套传入**认证标签(tag)**参数完成完整性校验,你当前代码完全没有处理tag参数,解密时校验不通过就会直接返回false。
修复方案
只需要在加解密时补充tag参数的传递即可,修改后的可运行代码如下:
$algo = 'aes-256-gcm'; $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($algo)); $data = "Data to Seal"; $tag = null; // 初始化tag变量接收加密生成的认证标签 $res = openssl_pkey_new(array( 'digest_alg' => 'sha256', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA )); openssl_pkey_export($res, $privkey); $pubkey = openssl_pkey_get_details($res); $pubkey = $pubkey["key"]; // 加密时追加第7个参数接收tag openssl_seal($data, $sealed, $envelope, array($pubkey), $algo, $iv, $tag); $openKey = openssl_pkey_get_private($privkey); // 解密时追加第7个参数传入加密生成的tag if (openssl_open($sealed, $open, $envelope[0], $openKey, $algo, $iv, $tag)) { echo "OPENED: ".$open; } else { echo "Failed to open Data!"; }
额外注意事项
- 如果你需要跨系统/跨请求做加解密,需要把
$iv、$envelope[0]、$tag三个值同步传输给解密端,三个值任意一个不匹配都会导致解密失败 - 如果你不想处理tag参数,可以把算法替换为非AEAD类算法比如
aes-256-cbc,但这类算法没有内置完整性校验,安全性弱于GCM模式
内容的提问来源于stack exchange,提问作者Sunny
相关产品推荐
相关产品推荐

