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

C#与PHP使用AES-128-CBC加密数据结果不一致问题求助

问题原因及解决方案

核心问题1:密钥处理不匹配

PHP与C#对密钥的处理逻辑存在差异,这是最常见的不匹配原因:

  • PHP的md5()函数默认返回32字符长度的十六进制字符串(32字节),而AES-128要求密钥长度为16字节,openssl_encrypt会自动将传入的密钥截断为前16字节使用。
  • 你当前C#代码中将MD5原始16字节哈希转成了32字符的十六进制字符串,再转UTF8得到32字节的密钥数组,此时如果设置KeySize=128会因密钥长度不匹配报错,若你隐式改成了256位密钥则完全和PHP逻辑不一致。

额外注意:如果PHP端实际使用的是md5('123456789', true)(返回16字节原始二进制哈希,这是加密场景下的常见写法,很多示例会漏写第二个参数),你C#中完全不需要将MD5哈希转成十六进制字符串,直接使用ComputeHash返回的16字节HashValue作为密钥即可。

核心问题2:明文编码引入额外字节

你使用StreamWriter写入明文,StreamWriter默认使用带BOM(字节顺序标记)的UTF8编码,会在明文开头额外写入3个字节的BOM标记,而PHP端的明文是无BOM的纯ASCII字符串,明文内容不一致自然加密结果不同。

核心问题3:加密参数未显式声明

Rijndael算法支持多种块大小和填充模式,你没有显式声明块大小和填充模式,不同.NET版本的默认值可能存在差异,和PHP端openssl_encrypt默认的PKCS7填充、128位块大小不匹配。


修正后的C#代码示例

string data = "data to be sent";
string base64data = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));

// 处理密钥
MD5 hasher = MD5.Create();
byte[] hashValue = hasher.ComputeHash(Encoding.UTF8.GetBytes("123456789"));

// 场景1:PHP端md5未加raw_output=true(返回32位十六进制字符串)
string encryptionKeyHex = BitConverter.ToString(hashValue).Replace("-", "").ToLower();
byte[] fullKeyBytes = Encoding.ASCII.GetBytes(encryptionKeyHex);
// 取前16字节作为AES-128密钥(和PHP截断逻辑一致)
byte[] keyBytes = new byte[16];
Array.Copy(fullKeyBytes, keyBytes, 16);

// 场景2:PHP端md5加了raw_output=true(返回16字节原始哈希,优先测试这个场景,更常用)
// byte[] keyBytes = hashValue;

byte[] iv = Encoding.ASCII.GetBytes("1234567891234567");

// 显式设置所有加密参数
using RijndaelManaged aes = new RijndaelManaged();
aes.Mode = CipherMode.CBC;
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Padding = PaddingMode.PKCS7;
aes.Key = keyBytes;
aes.IV = iv;

// 直接处理字节流,避免StreamWriter的编码问题
byte[] plainBytes = new UTF8Encoding(false).GetBytes(base64data);
using ICryptoTransform encryptor = aes.CreateEncryptor();
using MemoryStream msEncrypt = new MemoryStream();
using CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
csEncrypt.Write(plainBytes, 0, plainBytes.Length);
csEncrypt.FlushFinalBlock();

byte[] encryptedData = msEncrypt.ToArray();
Console.WriteLine($"Encrypted data: {Convert.ToBase64String(encryptedData)}");

内容的提问来源于stack exchange,提问作者V. Oikonomakos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:15:00