填充是无效的,而使用&QUOT解密字符串不能被删除异常; AesManaged" C# [英] Padding is invalid and cannot be removed Exception while decrypting string using "AesManaged" C#

查看:257
本文介绍了填充是无效的,而使用&QUOT解密字符串不能被删除异常; AesManaged" C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请给我建议,我需要更新/重构code摆脱例外。我得到的异常,而我尝试使用以下code解密加密的字符串。

行之后抛出异常。

 使用(StreamReader的srDecrypt =新的StreamReader(csDecrypt))
{
     //从解密流读取的字节数解密
     //并将其放置在一个字符串。
     明文= srDecrypt.ReadToEnd();
}公共字符串EncryptAuthenticationTokenAes(字符串明文)
{    字节[]加密;
    //创建一个AesManaged对象
    //使用指定的密钥和IV。
    使用(AesManaged aesAlg =新AesManaged())
    {        //创建一个decrytor执行流转换。
        ICryptoTransform的加密= aesAlg.CreateEncryptor(aesAlg.Key,aesAlg.IV);
        aesAlg.Padding = PaddingMode.None;
        //创建用于加密的数据流。
        使用(MemoryStream的msEncrypt =新的MemoryStream())
        {
            使用(CryptoStream的csEncrypt =新的CryptoStream(msEncrypt,加密,CryptoStreamMode.Write))
            {
                使用(StreamWriter的swEncrypt =新的StreamWriter(csEncrypt))
                {                    //写的所有数据流。
                    swEncrypt.Write(明文);
                }
                加密= msEncrypt.ToArray();
            }
        }
    }
    //从内存流返回加密的字节。
    返回Convert.ToBase64String(加密的);}公共字符串DecryptPasswordAes(字符串encryptedString)
{
    //将密文回字节数组
    字节[] =密文Convert.FromBase64String(encryptedString);    //声明用于保存字符串
    //解密文。
    字符串明文= NULL;    //创建一个AesManaged对象
    //使用指定的密钥和IV。
    使用(AesManaged aesAlg =新AesManaged())
    {
        //创建一个decrytor执行流转换。
        ICryptoTransform的解密= aesAlg.CreateDecryptor(aesAlg.Key,aesAlg.IV);
        aesAlg.Padding = PaddingMode.None;
        //创建用于解密的流。
        使用(MemoryStream的msDecrypt =新的MemoryStream(密文))
        {
            使用(CryptoStream的csDecrypt =新的CryptoStream(msDecrypt,解密,CryptoStreamMode.Read))
            {
                使用(StreamReader的srDecrypt =新的StreamReader(csDecrypt))
                {                    //从解密流读取的字节数解密
                    //并将其放置在一个字符串。
                    明文= srDecrypt.ReadToEnd();
                }
            }
        }    }    返回明文;}


解决方案

pretty标准错误使用CryptoStream的时候,你忘了,迫使它流的最后一个字节进行加密。它保持在一个内部缓冲区,直到足够他们到达字节发出块。您必须强制最后几个字节的。修正:

 使用(VAR msEncrypt =新的MemoryStream())
    使用(VAR csEncrypt =新的CryptoStream(msEncrypt,加密,CryptoStreamMode.Write))
    使用(VAR swEncrypt =新的StreamWriter(csEncrypt)){
        swEncrypt.Write(明文);
        csEncrypt.FlushFinalBlock();
        加密= msEncrypt.ToArray();
    }

您的解密它的时候,因为的加密缺少最终填充有例外。真正的问题是由引起的使用的声明,你不会,如果你等待获得加密字节,直到CryptoStream的关闭后有这个问题。但是,这并不正常工作,因为的使用的关于StreamWriter的声明也将关闭CryptoStream的和的MemoryStream。明确使用FlushFinalBlock()是最好的解决办法。

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. 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. 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.

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

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