C#中Rijndael解密仅返回16字符问题的修复方案咨询
Rijndael加密解密长字符串截断问题修复
问题描述
使用当前Rijndael加密解密方法时,加密16个字符以上的字符串后解密,结果最多仅返回16个字符。例如输入"ABCDEFGHIJKLMNOP12345678",解密后输出为"ABCDEFGHIJKLMNOP"。当前参数配置:hashAlgorithm="SHA1",passwordIterations=2,keySize=256。
问题原因
解密方法中仅调用了一次cryptoStream.Read(),而CryptoStream.Read()无法保证一次性读取所有解密后的数据——Rijndael默认块大小为128位(16字节),单次读取仅会返回第一个块的内容,后续数据直接丢失。
修复后的代码
public class RijndaelSimple { public static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) { byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); PasswordDeriveBytes password = new PasswordDeriveBytes( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); byte[] keyBytes = password.GetBytes(keySize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); using (MemoryStream memoryStream = new MemoryStream()) using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); return Convert.ToBase64String(cipherTextBytes); } } public static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) { byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); byte[] cipherTextBytes = Convert.FromBase64String(cipherText); PasswordDeriveBytes password = new PasswordDeriveBytes( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); byte[] keyBytes = password.GetBytes(keySize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes)) using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) using (MemoryStream plainTextStream = new MemoryStream()) { byte[] buffer = new byte[4096]; // 用4KB缓冲区分批读取数据 int bytesRead; while ((bytesRead = cryptoStream.Read(buffer, 0, buffer.Length)) > 0) { plainTextStream.Write(buffer, 0, bytesRead); } return Encoding.UTF8.GetString(plainTextStream.ToArray()); } } }
关键修改说明
- 解密逻辑优化:将单次
Read操作改为循环读取,直到Read返回0(无更多数据),确保所有解密后的内容都被读取。 - 资源自动管理:使用
using语句替代手动调用Close(),自动释放流资源,避免泄漏。 - 缓冲区效率提升:采用4KB大小的缓冲区分批处理数据,更适合长字符串的读写操作。
内容的提问来源于stack exchange,提问作者nicedev92
相关产品推荐
相关产品推荐

