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

C# AES加密问题:首尾空格触发CryptographicException异常

搞定C# AES加密里的填充和块大小异常

老兄,我之前做C# AES加密的时候也踩过一模一样的坑,来给你拆解下这两个问题的本质和正确解法:

第一个坑:Padding is invalid and cannot be removed.

你一开始遇到这个异常,说白了就是加密和解密的填充模式没对齐。AES是块加密算法,要求输入数据的字节长度必须是块大小(默认128位,也就是16字节)的整数倍,所以得靠“填充”来补全不够的部分。如果加密时用了默认的PaddingMode.PKCS7(.NET默认就是这个),但解密时你改成了None,那解密端找不到对应的填充标记,自然就报错了。你改成None能暂时解决,但这其实是绕开问题,不是真的解决——这也直接导致了你第二个坑。

第二个坑:The input data is not a complete block.

当你把填充设为None后,带空格的字符串转成字节后,长度刚好不是16的整数倍,AES直接就炸了,因为它要求输入必须是完整的块。你移除填充设置其实还是没碰根儿上的问题,反而让你的加密代码只能处理长度刚好是16倍数的字符串,太受限了。

正确的打开方式:保持加解密参数完全一致,用标准填充

其实根本不用去掉填充,只要保证加密和解密时的填充模式、块大小、密钥、IV完全匹配就行,统一用PaddingMode.PKCS7就好,框架会自动帮你处理填充和去填充的事儿,不用你手动纠结块大小。

给你一个能直接用的示例代码,不管字符串带不带空格都能正常加密解密:

using System;
using System.Security.Cryptography;
using System.Text;

public class AesHelper
{
    // 加密方法
    public static string EncryptString(string plainText, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7; // 统一用标准填充
            aes.Mode = CipherMode.CBC; // 常用模式,必须配IV

            var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            using (var ms = new System.IO.MemoryStream())
            {
                using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    using (var sw = new System.IO.StreamWriter(cs))
                    {
                        sw.Write(plainText);
                    }
                    return Convert.ToBase64String(ms.ToArray());
                }
            }
        }
    }

    // 解密方法
    public static string DecryptString(string cipherText, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7; // 和加密端完全一致
            aes.Mode = CipherMode.CBC;

            var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            using (var ms = new System.IO.MemoryStream(Convert.FromBase64String(cipherText)))
            {
                using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                {
                    using (var sr = new System.IO.StreamReader(cs))
                    {
                        return sr.ReadToEnd();
                    }
                }
            }
        }
    }
}

几个必须注意的点:

  • 填充模式绝对要一致:加密用PKCS7,解密也得用,不能一边用一边不用,不然肯定报错。
  • IV别瞎搞:如果用CBC模式(默认就是),必须生成随机的IV,加密时把IV和密文一起传给解密端,不能硬编码IV,不然安全性会很差。
  • 编码要统一:字符串转字节的时候,加密和解密要用同一种编码(比如UTF8),不然也可能出现奇怪的问题。

如果你真的有特殊需求必须用PaddingMode.None,那得手动把输入数据的字节长度补成16的整数倍(比如补0),解密后再手动去掉补的内容,但这种方式很容易出错,除非万不得已,真不推荐。

内容的提问来源于stack exchange,提问作者Bicycle-riding Dog

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:56:23