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

PHP转C#实现AES-256-CBC加密结果不匹配问题求助

问题原因

你的C#代码和PHP官方加密逻辑存在3处核心差异,导致输出结果不匹配:

  1. SHA256输出格式错误:PHP的hash('sha256', $str)默认返回小写的十六进制字符串,而你的C#代码直接返回SHA256的原始二进制字节,导致后续生成的密钥、IV完全不符合要求。
  2. 密钥与IV生成逻辑错误:PHP是对SHA256返回的十六进制字符串做截断生成密钥和IV,你的C#代码是直接对原始二进制字节做截断,逻辑完全不一致。
  3. Base64编码次数不足:PHP的openssl_encrypt在第四个参数为0时,默认返回已经做过一次base64编码的加密结果,原代码又对该结果做了第二次base64编码。而你的C#代码仅对加密后的原始二进制做了一次base64编码,少了一次编码步骤。

修复后的完整代码

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

// 计算SHA256并返回小写十六进制字符串,和PHP默认hash输出一致
static string Sha256ToHex(string rawData)
{
    using (SHA256 sha256 = SHA256.Create())
    {
        byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawData));
        StringBuilder sb = new StringBuilder();
        foreach (byte b in hashBytes)
        {
            sb.Append(b.ToString("x2"));
        }
        return sb.ToString();
    }
}

static string OpenSSLEncrypt(string plainText, string key)
{
    string keyHashHex = Sha256ToHex(key);
    string ivHashHex = Sha256ToHex(key);
    
    // AES-256需要32字节密钥,取十六进制串前32个字符转UTF8字节
    byte[] aesKey = Encoding.UTF8.GetBytes(keyHashHex.Substring(0, 32));
    // AES需要16字节IV,取十六进制串前16个字符转UTF8字节
    byte[] aesIv = Encoding.UTF8.GetBytes(ivHashHex.Substring(0, 16));

    using (Aes aes = Aes.Create())
    {
        aes.Key = aesKey;
        aes.IV = aesIv;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        ICryptoTransform encryptor = aes.CreateEncryptor();
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                csEncrypt.Write(plainBytes, 0, plainBytes.Length);
                csEncrypt.FlushFinalBlock();
            }
            // 第一次base64,对应openssl_encrypt的默认返回值
            string firstBase64 = Convert.ToBase64String(msEncrypt.ToArray());
            // 第二次base64,对应PHP代码中的base64_encode操作
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(firstBase64)).Trim();
        }
    }
}

注意事项

传入的明文必须和测试用例的明文完全一致,包括空格、换行、引号格式,不要做任何格式化调整,否则加密结果会不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:15:04