1

我需要执行字节[]的加密数组。我使用了 Microsoft 上提供的示例。不幸的是,加密数据被截断为 16 的倍数。如果在数据示例中我将添加 8 倍字节 0,则数据将被正确加密。填充已设置,但我没有看到任何可以更改的内容。如何解决这个问题,数据不被截断。

public byte[] EncryptAES(byte[] plainBytes)
{
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    byte[] FKey = encoding.GetBytes("A002AD9AD73C402190C3E733D82CEA00");
    byte[] FIV = encoding.GetBytes("zyxwvutsrqponmlk");

    // Check arguments.
    if (plainBytes == null || plainBytes.Length <= 0)
        throw new ArgumentNullException("plainText");
    if (FKey == null || FKey.Length <= 0)
        throw new ArgumentNullException("Key");
    if (FIV == null || FIV.Length <= 0)
        throw new ArgumentNullException("Key");
    byte[] encrypted;
    // Create an RijndaelManaged object
    // with the specified key and IV.
    using (RijndaelManaged rijAlg = new RijndaelManaged())
    {
        rijAlg.Key = FKey;
        rijAlg.IV = FIV;
        rijAlg.Padding = PaddingMode.Zeros;
        rijAlg.Mode = CipherMode.CBC;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

        // Create the streams used for encryption.
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                // plainBytes.Length = 2216 
                csEncrypt.Write(plainBytes, 0, plainBytes.Length);

                // encrypted.Length = 2208
                encrypted = msEncrypt.ToArray();
            }
        }
    }

    // Return the encrypted bytes from the memory stream.
    return encrypted;
}
4

3 回答 3

2

CryptoStream

使用完 CryptoStream 对象后,应始终通过调用Close方法显式关闭它。这样做会刷新流并导致所有剩余的数据块由 CryptoStream 对象处理。但是,如果在调用Close方法之前发生异常,则可能不会关闭 CryptoStream 对象。为确保始终调用Close方法,请将对Close方法的调用放在try/catch 语句的 finally 块中。

我的重点

所以,Close在你尝试对结果做任何事情之前打电话。


基本上,填充用于处理加密块序列的最后一个块。由于CryptoStream不知道您打算调用多少次Write(),因此在您调用之前它不会应用填充或写入任何最终的不完整块Close

(或者,正如 Monkieboy 指出的那样,FlushFinalBlock也可以用来表示你已经完成了)

于 2013-03-08T10:43:52.827 回答
2

只需调用 FlushFinalBlock() 即可解决 16 的倍数问题。

于 2015-01-20T03:54:56.090 回答
0

试试这个

    using (MemoryStream msEncrypt = new MemoryStream())
    {
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            csEncrypt.Write(plainBytes, 0, plainBytes.Length);
        }
        encrypted = msEncrypt.ToArray();
    }
于 2013-03-08T10:42:23.270 回答