Aes 加密 MemoryStream.ToArray 为空

本文关键字:为空 ToArray MemoryStream 加密 Aes | 更新日期: 2023-09-27 18:31:07

我对AesEncrypt有问题,我有这样一段加密文本的代码:

private byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
    // Check arguments. 
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");
    byte[] encrypted;
    // Create an Aes object 
    // with the specified key and IV. 
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Padding = PaddingMode.None;
        aesAlg.Key = Key;
        aesAlg.IV = IV;
        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
        // Create the streams used for encryption. 
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                    csEncrypt.FlushFinalBlock();
                }
            }
            encrypted = msEncrypt.ToArray();
        }
    }
    // Return the encrypted bytes from the memory stream. 
    return encrypted;
}

问题是在某些情况下,msEncrypt.ToArray()会返回我一个空byte[],在某些情况下,它运行良好......

请拯救我的一天!

Aes 加密 MemoryStream.ToArray 为空

您需要在调用FlushFinalBlock()之前刷新swEncrypt,以确保您尝试加密的所有数据都传递到CryptoStream

改变

swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();

swEncrypt.Write(plainText);
swEncrypt.Flush();
csEncrypt.FlushFinalBlock();

进行此更改后,如果输入不是块大小的倍数,则CryptoStream现在将引发异常,在 AES 的情况下为 16 字节。

您有两种方法可以解决此问题。

  1. 手动填充输入,最多填充块大小的倍数。对于"This is a test string",你会把它填充到类似这样的东西"This is a test string'0'0'0'0'0'0'0'0'0'0'0"。填充字符可以是您想要的任何字符,只需确保在解密后删除填充即可。
  2. 将填充模式更改为其他内容,例如 PKCS7Zeros 。除非您绝对需要使用PaddingMode.None(例如,为了与其他系统兼容),否则这是更好的解决方案。