简体   繁体   English

填充无效,无法删除使用“ AesManaged” C#解密字符串时发生异常

[英]Padding is invalid and cannot be removed Exception while decrypting string using “AesManaged” C#

Please suggest me where i need to update/refactor the code to get rid of exception. 请建议我在哪里我需要更新/重构代码以摆脱异常。 I am getting exception while I try to decrypt the encrypted string using following code. 我尝试使用以下代码解密加密的字符串时遇到异常。

Following line is throwing exception 下一行引发异常

using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
     // Read the decrypted bytes from the decrypting stream
     // and place them in a string.
     plaintext = srDecrypt.ReadToEnd();
}

public string EncryptAuthenticationTokenAes(string plainText)
{

    byte[] encrypted;
    // Create an AesManaged object
    // with the specified key and IV.
    using (AesManaged aesAlg = new AesManaged())
    {

        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
        aesAlg.Padding = PaddingMode.None;
        // 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))
                {

                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                }
                encrypted = msEncrypt.ToArray();
            }
        }
    }


    // Return the encrypted bytes from the memory stream.
    return Convert.ToBase64String(encrypted);

}

public string DecryptPasswordAes(string encryptedString)
{
    //Convert cipher text back to byte array
    byte[] cipherText = Convert.FromBase64String(encryptedString);

    // Declare the string used to hold
    // the decrypted text.
    string plaintext = null;

    // Create an AesManaged object
    // with the specified key and IV.
    using (AesManaged aesAlg = new AesManaged())
    {
        // Create a decrytor to perform the stream transform.
        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
        aesAlg.Padding = PaddingMode.None;
        // Create the streams used for decryption.
        using (MemoryStream msDecrypt = new MemoryStream(cipherText))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {

                    // Read the decrypted bytes from the decrypting stream
                    // and place them in a string.
                    plaintext = srDecrypt.ReadToEnd();
                }
            }
        }

    }

    return plaintext;

}

Pretty standard bug when using CryptoStream, you forgot to force it to encrypt the last bytes of the stream. 使用CryptoStream时,这是一个非常标准的错误,您忘记了强制它对流的最后一个字节进行加密。 It keeps bytes in an internal buffer until enough of them arrive to emit a block. 它将字节保留在内部缓冲区中,直到足够多的字节到达以发出一个块为止。 You must force the last few bytes out. 您必须将最后几个字节强制删除。 Fix: 固定:

    using (var msEncrypt = new MemoryStream())
    using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
    using (var swEncrypt = new StreamWriter(csEncrypt)) {
        swEncrypt.Write(plainText);
        csEncrypt.FlushFinalBlock();
        encrypted = msEncrypt.ToArray();
    }

You got the exception when decrypting it because encrypted is missing the final padding. 解密时遇到异常,因为加密缺少最后的填充。 The real problem is caused by the using statement, you wouldn't have this problem if you waited obtaining the encrypted bytes until after the CryptoStream is closed. 真正的问题是由using语句引起的,如果等到CryptoStream关闭后才等待获取加密的字节,就不会有此问题。 But that doesn't work well because the using statement on the StreamWriter also closes the CryptoStream and the MemoryStream. 但这并不能很好地工作,因为StreamWriter上的using语句还会关闭CryptoStream和MemoryStream。 Explicitly using FlushFinalBlock() is the best workaround. 最好使用FlushFinalBlock()是最好的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM