Aes加密MemoryStream.ToArray为空

时间:2013-09-13 09:46:31

标签: c# encryption aes

我遇到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[],在某些情况下,它会运作良好......

请保存我的一天!

1 个答案:

答案 0 :(得分:2)

您需要在致电swEncrypt之前刷新FlushFinalBlock(),以确保您尝试加密的所有数据都会传递到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(例如,为了与其他系统兼容),否则这是更好的解决方案。