You need to enable JavaScript to run this app. PHP中使用Hex密钥通过openssl_decrypt解密C# Rijndael加密串返回空的问题
优惠活动
大模型
产品
解决方案
定价
更多

PHP中使用Hex密钥通过openssl_decrypt解密C# Rijndael加密串返回空的问题

解密返回空的核心原因
  • 未处理加密结果的URL编码:C#代码最终输出的加密字符串经过Uri.EscapeDataString编码,包含%2F、%3D这类URL转义字符,直接传入base64_decode会得到损坏的二进制数据,无法作为合法密文使用。
  • 密钥处理逻辑完全错误:
    • 提供的密钥是64位长度的十六进制字符串,对应二进制长度为32字节,匹配的AES算法是aes-256-cbc,原代码里选的aes-128-cbc要求密钥长度为16字节,本身就存在长度不匹配的问题。
    • 原代码通过unpack('C*', $key)再拼接的方式,是把密钥字符串本身的ASCII值作为密钥使用,完全没有做十六进制到二进制的转换,生成的密钥长度超过60个字节,完全不符合AES算法的密钥长度要求,openssl会直接判定参数非法返回空。
  • 未按C#的逻辑拆分IV:C#加密时将16字节的随机IV直接拼接在密文块的最前端,原代码把整个含IV的二进制块直接当成密文传给解密函数,既没有拆分出独立的IV,也没有在调用openssl_decrypt时传入IV参数,CBC模式没有合法初始向量根本无法完成解密。
  • 因为开启了严格的零填充校验模式,只要前面任意一步参数错误,openssl不会抛出具体错误,直接返回空字符串,放大了排查难度。
正确的解密实现
  1. 先对加密串做urldecode还原成纯base64字符串,再做base64解码,得到“IV+密文”的拼接二进制块。
  2. 从拼接块的前16个字节截取作为CBC模式需要的IV,剩余部分为实际加密的密文内容。
  3. 将十六进制格式的密钥通过hex2bin转成32字节的二进制密钥,匹配aes-256-cbc的要求。
  4. 调用openssl解密时传入正确的算法、密钥、拆分得到的IV,搭配OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING标记匹配C#的Zeros填充规则,最后移除解密结果末尾的零填充即可得到明文。
可运行的参考代码
function decrypt(string $encryptedString, string $hexKey): string
{
    // 还原URL编码的base64字符串
    $urlDecoded = urldecode($encryptedString);
    // 解码得到IV与密文的拼接二进制块
    $rawBinary = base64_decode($urlDecoded);
    // 拆分前16字节为CBC模式需要的IV
    $iv = substr($rawBinary, 0, 16);
    $actualCipher = substr($rawBinary, 16);
    // 十六进制密钥转成匹配长度的二进制密钥
    $binaryKey = hex2bin($hexKey);
    // 执行解密匹配C#的Zeros填充规则
    $decrypted = openssl_decrypt(
        $actualCipher,
        'aes-256-cbc',
        $binaryKey,
        OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
        $iv
    );
    // 移除末尾的零填充
    return rtrim($decrypted, "\0");
}

// 测试调用
$cipherText = "O0wTQerC%2FQs5sFUMc3uXoSkrsJcY7toWqlsQYRYAD64%3D";
$key = "2b8958eb1da990c039933a504259059fc9c8a893447fcbb3a8c504797e637288";
echo decrypt($cipherText, $key);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 22:15:03