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

PHP openssl BF-CBC模式解密已加密字符串无返回值问题

问题根因

解密无返回是三个逻辑点共同导致的:

  1. IV不匹配:代码中使用的BF-CBC即Blowfish-CBC,属于CBC模式的分组加密算法,解密必须使用和加密时完全一致的初始化向量(IV)。原代码在解密环节调用random_bytes生成了全新的随机IV,和加密时用的IV完全不同,直接导致解密失败。
  2. IV未随密文传递:加密时生成的随机IV没有和密文绑定返回,解密方根本无法获取加密时使用的正确IV。
  3. 无可见输出的直接原因:openssl_decrypt解密失败时会返回布尔值false,PHP中直接echo false不会输出任何可见字符,看起来就像程序没有响应,实际用var_dump打印解密结果就能看到返回值是bool(false)。
修复方案

修复逻辑非常直接:加密时把生成的IV拼接在密文前,统一编码后返回;解密时先从传入的串中拆分出对应长度的IV,再用这个IV执行解密操作。IV不需要保密,只要加密时随机生成即可,和密文一起传递不会降低安全性。

function encrypt($string, $key)
{
    $method = "BF-CBC";
    $ivLength = openssl_cipher_iv_length($method);
    $iv = random_bytes($ivLength);
    $options = 0;
    $key = hash("sha256", $key);
    $ciphertext = openssl_encrypt($string, $method, $key, $options, $iv);
    // 把IV和密文拼接后base64编码返回
    return base64_encode($iv . $ciphertext);
}

function decrypt($string, $key)
{
    $method = "BF-CBC";
    $ivLength = openssl_cipher_iv_length($method);
    $options = 0;
    $key = hash("sha256", $key);
    // 解码后拆分出IV和真实密文
    $decodedData = base64_decode($string);
    $iv = substr($decodedData, 0, $ivLength);
    $realCiphertext = substr($decodedData, $ivLength);
    return openssl_decrypt($realCiphertext, $method, $key, $options, $iv);
}
测试验证
// 加密foo
$encrypted = encrypt("foo", "hfgdhgdfhgfd");
echo "加密结果:" . $encrypted . PHP_EOL;

// 解密
$decrypted = decrypt($encrypted, "hfgdhgdfhgfd");
echo "解密结果:" . $decrypted . PHP_EOL;

执行后会正常输出解密后的foo。

注意:之前用旧版encrypt函数生成的密文无法解密,因为当时加密用的随机IV没有被保存,已经永久丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:24:30