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

.NET 7 AES解密出现‘填充无效且无法移除’错误求助

问题分析与修复方案

你的问题出在解密过程中没有使用从密文中提取的正确IV,而是误用了Aes实例自动生成的新IV,这直接导致解密乱码和填充错误。另外还有细节需要补全,具体修复如下:

核心错误点

  • IV使用错误:Decrypt方法里,你调用aesAlg.CreateDecryptor(key, aesAlg.IV)时,aesAlg.IV是Aes实例新生成的随机值,不是加密时用的那个。必须传入从密文中分离出的cbcCiphertext.IV。
  • 未显式指定加密模式:加密时设置了CipherMode.CBC,解密时最好显式同步设置,避免因系统默认值变化引发问题。

修复后的完整代码

public class AesEncryption
{
    private static byte[] key = new byte[32] { /* 你的256位密钥 */ }; // 256-bit key
    public static string Encrypt(string plaintext)
    {
        using (Aes aesAlg = Aes.Create())
        {
            var iv = aesAlg.IV;
            aesAlg.Mode = CipherMode.CBC;
            aesAlg.Padding = PaddingMode.PKCS7;
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(key, iv);
            byte[] encryptedBytes;
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var streamWriter = new StreamWriter(csEncrypt))
                    {
                        streamWriter.Write(plaintext);
                    }
                }
                encryptedBytes = msEncrypt.ToArray();
            }
            return new AesCbcCiphertext(iv, encryptedBytes).ToString();
        }
    }

    public static string Decrypt(string ciphertext)
    {
        var cbcCiphertext = AesCbcCiphertext.FromBase64String(ciphertext);
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Mode = CipherMode.CBC; // 与加密模式保持一致
            aesAlg.Padding = PaddingMode.PKCS7;
            // 使用从密文中提取的正确IV
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(key, cbcCiphertext.IV);
            using (var msDecrypt = new MemoryStream(cbcCiphertext.CiphertextBytes))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var streamReader = new StreamReader(csDecrypt))
                    { 
                        return streamReader.ReadToEnd();
                    }
                }
            }
        }
    }
}

internal class AesCbcCiphertext
{
    public byte[] IV { get; }
    public byte[] CiphertextBytes { get; }

    public static AesCbcCiphertext FromBase64String(string data)
    {
        var dataBytes = Convert.FromBase64String(data);
        return new AesCbcCiphertext(
            dataBytes.Take(16).ToArray(),
            dataBytes.Skip(16).ToArray()
        );
    }

    public AesCbcCiphertext(byte[] iv, byte[] ciphertextBytes)
    {
        IV = iv;
        CiphertextBytes = ciphertextBytes;
    }

    public override string ToString()
    {
        var total = IV.Concat(CiphertextBytes).ToArray();
        return Convert.ToBase64String(total); // 优化:直接使用已拼接的数组
    }
}

额外说明

  • IV在AES-CBC模式中至关重要:它能让相同明文用同一密钥加密时生成不同密文,防止模式重复被攻击者利用。解密必须使用和加密完全一致的IV,否则无法正确还原明文,甚至触发填充错误。
  • 硬编码固定IV时正常,是因为加密和解密用了同一个固定值,但这种做法不安全,你使用可变IV的思路是正确的,只是解密时IV用错了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:25:19