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

AES解密结果异常:部分字符丢失问题求助

AES解密后字符丢失问题修复

问题重现

使用AES加密字符串"5&&64&&41&&false&&&&dc&&"后解密,结果仅得到"5&&64&&41&&false",末尾的"&&&&dc&&"丢失。原代码如下:

public class Program
{
    static void Main(string[] args)
    {
        Program program = new Program();
        var toEncryptReturn = program.EncryptString("5&&64&&41&&false&&&&dc&&", "mysmallkey123456");
        var toDecryptReturn = program.DecryptString(toEncryptReturn, "mysmallkey123456");
    }

    public string EncryptString(string text, string keyString)
    {
        var key = Encoding.UTF8.GetBytes(keyString);

        using (var aesAlg = Aes.Create())
        {
            using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
            {
                aesAlg.Padding = PaddingMode.None;
                using (var msEncrypt = new MemoryStream())
                {
                    using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(text);
                    }

                    var iv = aesAlg.IV;

                    var decryptedContent = msEncrypt.ToArray();

                    var result = new byte[iv.Length + decryptedContent.Length];

                    Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
                    Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
                    
                    return Convert.ToBase64String(result);
                }
            }
        }
    }
    public string DecryptString(string cipherText, string keyString)
    {
        var fullCipher = Convert.FromBase64String(cipherText);

        var iv = new byte[16];
        var cipher = new byte[16];

        Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
        Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
        var key = Encoding.UTF8.GetBytes(keyString);

        using (var aesAlg = Aes.Create())
        {
            aesAlg.Padding = PaddingMode.None;
            using (var decryptor = aesAlg.CreateDecryptor(key, iv))
            {
                string result;
                using (var msDecrypt = new MemoryStream(cipher))
                {
                    using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (var srDecrypt = new StreamReader(csDecrypt))
                        {
                            result = srDecrypt.ReadToEnd();
                        }
                    }
                }

                return result;
            }
        }
    }
}

错误原因

  1. PaddingMode.None导致数据截断:
    AES是块加密算法,固定块大小为16字节。当设置PaddingMode.None时,加密数据的字节长度必须是16的整数倍,否则超出部分会被丢弃。原字符串转UTF8字节后长度为24,不是16的倍数,因此加密时仅处理了前16字节对应的字符,剩余8字节内容被截断。

  2. 解密时硬编码密文长度:
    解密代码中直接将密文长度固定为16字节,忽略了实际加密后的数据长度,导致仅解密了前16字节的内容。

  3. AES参数设置顺序错误:
    在创建Encryptor之后才设置PaddingMode.None,此时加密器已使用默认的Padding配置初始化,设置不生效。

修复方案

  1. 使用默认的PaddingMode.PKCS7(或按需选择合适的填充模式),自动处理块大小对齐问题,避免手动截断。
  2. 先配置AES的Key、IV、Padding等参数,再创建加密/解密器。
  3. 解密时根据实际密文长度提取数据,不硬编码长度。
  4. 确保加密完成后CryptoStream完成所有写入操作(using语句可自动处理,但需保证流正确关闭)。

修正后的代码

public class Program
{
    static void Main(string[] args)
    {
        Program program = new Program();
        var encrypted = program.EncryptString("5&&64&&41&&false&&&&dc&&", "mysmallkey123456");
        var decrypted = program.DecryptString(encrypted, "mysmallkey123456");
        // 输出:5&&64&&41&&false&&&&dc&&
        Console.WriteLine(decrypted);
    }

    public string EncryptString(string text, string keyString)
    {
        var key = Encoding.UTF8.GetBytes(keyString);
        // AES密钥长度必须是16、24或32字节,这里keyString是16字节,符合要求
        if (key.Length != 16 && key.Length != 24 && key.Length != 32)
        {
            throw new ArgumentException("密钥长度必须为16、24或32字节");
        }

        using (var aesAlg = Aes.Create())
        {
            aesAlg.Key = key;
            aesAlg.GenerateIV(); // 自动生成随机IV
            aesAlg.Padding = PaddingMode.PKCS7; // 使用PKCS7填充

            using (var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
            using (var msEncrypt = new MemoryStream())
            {
                // 先写入IV到结果,方便解密时使用
                msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);

                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                using (var swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(text);
                }

                return Convert.ToBase64String(msEncrypt.ToArray());
            }
        }
    }

    public string DecryptString(string cipherText, string keyString)
    {
        var fullCipher = Convert.FromBase64String(cipherText);
        var key = Encoding.UTF8.GetBytes(keyString);
        if (key.Length != 16 && key.Length != 24 && key.Length != 32)
        {
            throw new ArgumentException("密钥长度必须为16、24或32字节");
        }

        // 提取IV(前16字节)
        var iv = new byte[16];
        Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
        // 提取实际密文(IV之后的所有字节)
        var cipher = new byte[fullCipher.Length - iv.Length];
        Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length);

        using (var aesAlg = Aes.Create())
        {
            aesAlg.Key = key;
            aesAlg.IV = iv;
            aesAlg.Padding = PaddingMode.PKCS7;

            using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
            using (var msDecrypt = new MemoryStream(cipher))
            using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (var srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:15:37