使用“AesManaged"解密字符串时填充无效且无法删除异常C# [英] Padding is invalid and cannot be removed Exception while decrypting string using "AesManaged" C#

查看:51
本文介绍了使用“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.

下面一行抛出异常

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;

}

推荐答案

使用 CryptoStream 时的一个标准错误,您忘记强制它加密流的最后一个字节.它将字节保存在内部缓冲区中,直到有足够的字节到达以发出块为止.您必须强制输出最后几个字节.修复:

Pretty standard bug when using CryptoStream, you forgot to force it to encrypt the last bytes of the stream. 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();
    }

您在解密时遇到异常,因为 encrypted 缺少最后的填充.真正的问题是由 using 语句引起的,如果您等到 CryptoStream 关​​闭后才获取加密字节,则不会出现此问题.但这并不奏效,因为 StreamWriter 上的 using 语句也关闭了 CryptoStream 和 MemoryStream.明确使用 FlushFinalBlock() 是最好的解决方法.

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. But that doesn't work well because the using statement on the StreamWriter also closes the CryptoStream and the MemoryStream. Explicitly using FlushFinalBlock() is the best workaround.

这篇关于使用“AesManaged"解密字符串时填充无效且无法删除异常C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆