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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:13:11