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

Rijndael加密报错‘BlockSize必须为128’的解决方案求助

解决Rijndael加密报错“BlockSize must be 128 in this implementation”的方案

问题根源

.NET平台下的Rijndael实现(包括RijndaelManaged)仅支持128位块大小,它本质是AES标准的实现(AES是Rijndael的子集,固定128位块大小)。代码中设置BlockSize = 256超出了实现支持范围,因此触发错误。

修改步骤及完整代码

以下是适配.NET实现的修改后代码,核心调整点:

  • 将块大小改为128位
  • 调整IV(初始化向量)长度为16字节(与128位块大小匹配)
  • 修正加密后字节数组的拼接逻辑,以及解密时的拆分逻辑
internal static string Encrypt(string plainText, string passPhrase)
{
    byte[] salt = GetSaltArray();
    byte[] iv = GetIVArray();
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);

    using Rfc2898DeriveBytes keyDeriver = new Rfc2898DeriveBytes(passPhrase, salt, 1000);
    byte[] key = keyDeriver.GetBytes(32); // 256位密钥,Rijndael支持该长度

    using RijndaelManaged rijndael = new RijndaelManaged();
    rijndael.BlockSize = 128; // 修改为128位块大小
    rijndael.Mode = CipherMode.CBC;
    rijndael.Padding = PaddingMode.PKCS7;

    using ICryptoTransform encryptor = rijndael.CreateEncryptor(key, iv);
    using MemoryStream ms = new MemoryStream();
    using CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
    
    cs.Write(plainBytes, 0, plainBytes.Length);
    cs.FlushFinalBlock();

    // 拼接顺序:salt(32字节) + iv(16字节) + 密文
    byte[] encryptedData = salt.Concat(iv).Concat(ms.ToArray()).ToArray();
    return Convert.ToBase64String(encryptedData);
}

internal static string Decrypt(string cipherText, string passPhrase)
{
    byte[] encryptedBytes;
    try
    {
        encryptedBytes = Convert.FromBase64String(cipherText);
    }
    catch
    {
        return string.Empty;
    }

    // 拆分字节数组:前32字节是salt,接下来16字节是iv,剩余是密文
    byte[] salt = encryptedBytes.Take(32).ToArray();
    byte[] iv = encryptedBytes.Skip(32).Take(16).ToArray();
    byte[] cipherBytes = encryptedBytes.Skip(48).ToArray();

    using Rfc2898DeriveBytes keyDeriver = new Rfc2898DeriveBytes(passPhrase, salt, 1000);
    byte[] key = keyDeriver.GetBytes(32);

    using RijndaelManaged rijndael = new RijndaelManaged();
    rijndael.BlockSize = 128; // 修改为128位块大小
    rijndael.Mode = CipherMode.CBC;
    rijndael.Padding = PaddingMode.PKCS7;

    using ICryptoTransform decryptor = rijndael.CreateDecryptor(key, iv);
    using MemoryStream ms = new MemoryStream(cipherBytes);
    using CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
    
    byte[] plainBytes = new byte[cipherBytes.Length];
    int readCount = cs.Read(plainBytes, 0, plainBytes.Length);

    return Encoding.UTF8.GetString(plainBytes, 0, readCount);
}

// 生成32字节的盐值
private static byte[] GetSaltArray()
{
    byte[] salt = new byte[32];
    using RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(salt);
    return salt;
}

// 生成16字节的IV(匹配128位块大小)
private static byte[] GetIVArray()
{
    byte[] iv = new byte[16];
    using RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(iv);
    return iv;
}

关键说明

  1. 块大小限制:.NET的Rijndael实现不支持256位块大小,必须固定为128位,这是平台实现的硬性限制,无法绕过。
  2. IV长度匹配:CBC模式下IV长度必须与块大小一致,因此从32字节改为16字节。
  3. 兼容性:修改后的代码保留了原有的密钥推导逻辑(Rfc2898DeriveBytes)和256位密钥,仅调整块大小和IV相关逻辑,尽可能保留原有加密逻辑的核心。

内容的提问来源于stack exchange,提问作者living_mantis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:27:11