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

openssl_decrypt异常:自定义加密函数加密后解密返回空值

问题分析与解决方案

这个问题的核心在于**openssl_encrypt函数的$tag参数是引用传递**,而你的自定义mc_encrypt函数没有正确处理这个特性,导致解密时使用了错误的认证标签。

具体原因

在GCM加密模式下,openssl_encrypt的第6个参数$tag是用来输出加密过程中生成的认证标签的,它要求以引用的方式传入(PHP中用&标记)。当你直接调用openssl_encrypt时,外部的$tag变量会被自动更新为新生成的标签;但你的mc_encrypt函数把$tag当作普通值参数传入,函数内部对$tag的修改无法同步到外部,导致解密时使用的还是你最初解码的旧标签,标签验证失败,所以openssl_decrypt返回空值。

修改后的代码

只需要把mc_encrypt函数中的$tag参数改为引用传递即可:

$key = base64_decode("PRIV KEY");
$cipher = "aes-256-gcm";
$iv = base64_decode("BASE64 encoded IV ");
$tag = ""; // 初始化空标签,加密时会被自动填充

function mc_encrypt($plaintext, $cipher, $key, $iv, &$tag){
    // $tag是引用传递,加密后会同步更新外部的$tag变量
    $encrypted_text = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
    return base64_encode($encrypted_text); // 统一处理base64编码,避免默认行为混淆
}

function mc_decrypt($encrypted_text, $cipher, $key, $iv, $tag){
    $encrypted_text = base64_decode($encrypted_text);
    $decrypted_text = openssl_decrypt($encrypted_text, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
    return $decrypted_text; 
}

$test = "Teststring";

// 使用自定义函数加密,此时$tag会被更新为本次加密生成的新标签
$encrypted = mc_encrypt($test, $cipher, $key, $iv, $tag);

$decrypted = mc_decrypt($encrypted, $cipher, $key, $iv, $tag);
if($decrypted == $test)
{
    echo "Success!";
}

额外说明

  1. 我添加了OPENSSL_RAW_DATA选项,让加密返回原始二进制数据后再手动base64编码,这样能避免默认自动编码带来的逻辑混淆,也让加密解密的编码逻辑更统一。
  2. 从安全角度来说,GCM模式要求每次加密使用唯一的IV(即使密钥相同),测试时可以用随机IV生成代码:$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:11:18