为什么.NET与JavaScript中AES256CBC加密相同参数结果不一致?
问题原因及修复方案
1. .NET代码核心错误
你在.NET中已经将待加密字符串转为了UTF8字节数组data,但错误使用StreamWriter写入字节数组:StreamWriter是文本写入工具,当传入byte[]类型参数时,会自动调用其ToString()方法,实际加密的是字符串System.Byte[]对应的字节,而非你预期的Test123!的字节内容。
.NET代码修复:
删除StreamWriter层,直接将字节数组写入CryptoStream:
public static void Test() { var dataToEnc = "Test123!"; var keyB64 = "sy/d1Ddy/9K3p8x6pWMq2P8Qw2ftUjkkrAA7xFC7aK8="; var viB64 = "t8eI2F+QmlUBWZJVIlTX6Q=="; var key = Convert.FromBase64String(keyB64); var iv = Convert.FromBase64String(viB64); var data = Encoding.UTF8.GetBytes(dataToEnc); byte[] encrypted = null; using (Aes aesAlg = Aes.Create()) { aesAlg.Key = key; aesAlg.IV = iv; // 显式声明模式和填充,避免环境默认值差异 aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { // 直接写入字节数组,不要用StreamWriter csEncrypt.Write(data, 0, data.Length); csEncrypt.FlushFinalBlock(); } encrypted = msEncrypt.ToArray(); } } }
2. JavaScript代码优化(可选但推荐)
你当前的convertStringToArrayBuffer实现只对ASCII字符有效,如果待加密内容包含中文等多字节UTF8字符,会和.NET的Encoding.UTF8.GetBytes结果不一致,建议替换为标准的TextEncoder实现,保证UTF8编码对齐:
// 替换原来的convertStringToArrayBuffer相关逻辑 const encoder = new TextEncoder(); // 默认输出标准UTF8编码的字节数组 let dataInBytes = encoder.encode(dataToEnc); let key = window.atob(keyB64); let iv = window.atob(viB64); let keyBytes = encoder.encode(key); let ivBytes = encoder.encode(iv); window.crypto.subtle.importKey("raw", keyBytes.buffer, {name: "AES-CBC", length: 256}, false, ["encrypt"]).then(function(key){ window.crypto.subtle.encrypt({name: "AES-CBC", iv: ivBytes.buffer}, key, dataInBytes.buffer).then(function(encrypted){ console.log(encrypted); }); });
额外验证点
- 两边填充模式默认都是PKCS7,和AES-CBC标准要求对齐,无额外配置问题
- 你提供的base64密钥解码后为32字节,符合AES256的长度要求,密钥、IV解析逻辑本身没有问题
内容的提问来源于stack exchange,提问作者lasjan
相关产品推荐
相关产品推荐

