AES加密方法中字节数组为空导致加密结果为空,如何解决?
问题解决:AES加密后内存流为空的处理
核心原因
在读取内存流数据前,未确保StreamWriter和CryptoStream完成数据写入:
StreamWriter默认有缓冲区,写入的文本不会立即全部写入底层的CryptoStreamCryptoStream在写入模式下,需要完成最后一块数据的加密填充操作,直接读取会导致内存流无内容
解决方法
- 先调用
streamWriter.Flush()强制刷新缓冲区,再调用cryptoStream.FlushFinalBlock()完成加密收尾 - 加密后的二进制数据不能直接用UTF8转字符串,需改用Base64编码避免数据损坏
修正后的完整代码
using System.Security.Cryptography; using System.Text; Crypto crypto = new(); string test = "test"; string encrypted = crypto.EncryptString(test); string decrypted = crypto.DecryptString(encrypted); Console.WriteLine($"{test}\n{encrypted}\n{decrypted}"); Console.ReadKey(); class Crypto { byte[] key = Encoding.UTF8.GetBytes("01234567890123456789012345678901"); byte[] iv = new byte[16]; public string EncryptString(string plainText) { using Aes aes = Aes.Create(); aes.Key = key; aes.IV = iv; ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); using MemoryStream memoryStream = new(); using CryptoStream cryptoStream = new(memoryStream, encryptor, CryptoStreamMode.Write); using StreamWriter streamWriter = new(cryptoStream); streamWriter.Write(plainText); // 刷新缓冲区,确保文本写入CryptoStream streamWriter.Flush(); // 完成加密最后一块数据的填充处理 cryptoStream.FlushFinalBlock(); byte[] encryptedBytes = memoryStream.ToArray(); // 用Base64编码将二进制转为安全字符串 return Convert.ToBase64String(encryptedBytes); } public string DecryptString(string cipherText) { using Aes aes = Aes.Create(); aes.Key = key; aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); // 将Base64字符串转回二进制数组 byte[] cipherBytes = Convert.FromBase64String(cipherText); using MemoryStream memoryStream = new(cipherBytes); using CryptoStream cryptoStream = new(memoryStream, decryptor, CryptoStreamMode.Read); using StreamReader streamReader = new(cryptoStream); return streamReader.ReadToEnd(); } }
额外注意事项
- 生产环境中禁止使用固定IV,每次加密应生成随机IV(
aes.GenerateIV()),并将IV与加密数据一同存储(比如拼接在Base64字符串前),解密时提取使用,提升安全性 - 密钥应妥善保管,避免硬编码在代码中,建议使用配置文件或密钥管理服务
内容的提问来源于stack exchange,提问作者Perotto
相关产品推荐
相关产品推荐

