C# DLL启用AES 128位块大小加密时崩溃的排查问询
问题:AES加密调整块大小后C# DLL崩溃排查
原本使用托管Rijndael加密方案,采用256位密钥+256位块大小,DLL可正常运行;但接收端的.NET基础服务仅支持128位块大小,修改块大小为128位后,DLL执行加密操作时直接崩溃。尝试过多种C# AES实现(包括AesCryptoServiceProvider、AesManaged等),所有实现调用加密函数时均会触发崩溃。已生成32位和64位版本的DLL,加密约1000字符的字符串时均出现问题。求问是否存在遗漏的初始化步骤,或是否需要调整内存/栈大小,希望得到排查建议。
原代码(块大小256位可行,改为128位崩溃)
public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) { byte[] encryptedBytes = null; // Set your salt here, change it to meet your flavor: // The salt bytes must be at least 8 bytes. byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; using (MemoryStream ms = new MemoryStream()) { using (RijndaelManaged AES = new RijndaelManaged()) { AES.KeySize = 256; AES.BlockSize = 128; var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Mode = CipherMode.CBC; using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length); cs.Close(); } encryptedBytes = ms.ToArray(); } } return encryptedBytes; }
尝试过的其他实现
// 实现1 byte[] ivBytes = ComputeSHA256(iVphrase); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = ComputeSHA256(password); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.BlockSize = 128; aes.KeySize = 256; aes.Key = keyBytes; aes.IV = ivBytes; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; ICryptoTransform crypto1 = aes.CreateEncryptor(aes.Key, aes.IV); byte[] encrypteddata = crypto1.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length); crypto1.Dispose(); return Convert.ToBase64String(encrypteddata); // 实现2 byte[] encryptedData; byte[] ivBytes = ComputeSHA256(iVphrase); byte[] keyBytes = ComputeSHA256(password); using (Aes aesAlgorithm = new AesManaged()) { ICryptoTransform encryptor = aesAlgorithm.CreateEncryptor(keyBytes, ivBytes); //Encryption will be done in a memory stream through a CryptoStream object using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { using (StreamWriter sw = new StreamWriter(cs)) { sw.Write(plainText); } encryptedData = ms.ToArray(); } } return Convert.ToBase64String(encryptedData); } // 实现3 byte[] ivBytes = ComputeSHA256(iVphrase); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = ComputeSHA256(password); using (var symmetricKey = Aes.Create("AesManaged")) { symmetricKey.BlockSize = 128; symmetricKey.Mode = CipherMode.CBC; symmetricKey.Padding = PaddingMode.PKCS7; symmetricKey.Key = keyBytes; symmetricKey.IV = ivBytes; using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes)) { using (var memoryStream = new MemoryStream()) { using (var cs = new CryptoStream(memoryStream, symmetricKey.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(plainTextBytes, 0, plainTextBytes.Length); cs.Close(); } var cipherBytes = memoryStream.ToArray(); memoryStream.Close(); return Convert.ToBase64String(cipherBytes); } } }
排查建议
- 检查IV和Key的长度匹配:AES-256要求Key为32字节(256位),128位块大小对应的IV必须是16字节(128位)。你部分实现中用
ComputeSHA256生成IV,SHA256输出是32字节,直接赋值会导致IV长度不匹配,这是引发崩溃的常见原因,需截取前16字节作为IV。 - 捕获并记录异常:在加密函数外层添加
try-catch块,捕获所有异常并写入本地日志(如文本文件),崩溃大概率是未处理异常导致,日志能明确错误类型和位置。 - 验证托管环境兼容性:若DLL被非托管程序调用,需确认.NET运行时版本是否与调用方兼容,同时检查P/Invoke参数传递是否存在内存错误(比如字符串、字节数组的传递方式)。
- 确保资源正确释放:所有实现
IDisposable接口的对象(如CryptoStream、Aes实例)必须通过using语句或手动调用Dispose()释放,避免资源泄漏累积导致崩溃。 - 测试最小用例:先测试加密短字符串(如10字符),确认是否还会崩溃,逐步扩大输入长度,排查是否是大内存操作引发的栈溢出或内存问题。
- 统一加密配置参数:确保所有AES实现的
Mode、Padding等参数完全一致,不同配置组合可能引发不可预期的错误。
内容的提问来源于stack exchange,提问作者Barry Andrews
相关产品推荐
相关产品推荐

