C# 填充无效,无法删除。在cs.FlushFinalBlock()行触发错误

C# 填充无效,无法删除。在cs.FlushFinalBlock()行触发错误,c#,encryption,rijndael,rijndaelmanaged,C#,Encryption,Rijndael,Rijndaelmanaged,我正在尝试使用Rijndael方法对数据进行加密和解密。它加密很好,但当我尝试解密它时,它给出的填充无效,无法删除cs.FlushFinalBlock()行中的方法。我尝试了很多来源,比如 我知道这是一个常见的问题,甚至可能是一个重复的问题。我从早上开始在网上搜索,没有找到解决办法。下面是我的代码 //clearText -> the string to be encrypted //passowrd -> encryption key public

我正在尝试使用
Rijndael
方法对数据进行加密和解密。它加密很好,但当我尝试解密它时,它给出的
填充无效,无法删除
cs.FlushFinalBlock()行中的
私有静态字节[]解密字符串(字节[]密码数据,字节[]密钥,字节[]IV)中的code>
方法。我尝试了很多来源,比如

我知道这是一个常见的问题,甚至可能是一个重复的问题。我从早上开始在网上搜索,没有找到解决办法。下面是我的代码

    //clearText -> the string to be encrypted
    //passowrd -> encryption key
    public string EncryptString(string clearText, string Password)
    {
        // First we need to turn the input string into a byte array. 
        byte[] clearBytes =
            Encoding.Unicode.GetBytes(clearText);

        // Then, we need to turn the password into Key and IV 
        // We are using salt to make it harder to guess our key
        // using a dictionary attack - 
        // trying to guess a password by enumerating all possible words. 
        var pdb = new PasswordDeriveBytes(Password,
                                          new byte[]
                                              {
                                                  0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
                                                  0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
                                              });

        // Now get the key/IV and do the encryption using the
        // function that accepts byte arrays. 
        // Using PasswordDeriveBytes object we are first getting
        // 32 bytes for the Key 
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV. 
        // IV should always be the block size, which is by default
        // 16 bytes (128 bit) for Rijndael. 
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size. 
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes. 
        byte[] encryptedData = EncryptString(clearBytes,
                                             pdb.GetBytes(32), pdb.GetBytes(16));

        // Now we need to turn the resulting byte array into a string. 
        // A common mistake would be to use an Encoding class for that.
        //It does not work because not all byte values can be
        // represented by characters. 
        // We are going to be using Base64 encoding that is designed
        //exactly for what we are trying to do. 
        return Convert.ToBase64String(encryptedData);
    }
    //cipherText -> the string to be decrypted
    //passowrd -> decryption key
    public string DecryptString(string cipherText, string Password)
    {
        // First we need to turn the input string into a byte array. 
        // We presume that Base64 encoding was used 
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Then, we need to turn the password into Key and IV 
        // We are using salt to make it harder to guess our key
        // using a dictionary attack - 
        // trying to guess a password by enumerating all possible words. 
        var pdb = new PasswordDeriveBytes(Password,
                                          new byte[]
                                              {
                                                  0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
                                                  0x64, 0x76, 0x65, 0x64, 0x65, 0x76
                                              });

        // Now get the key/IV and do the decryption using
        // the function that accepts byte arrays. 
        // Using PasswordDeriveBytes object we are first
        // getting 32 bytes for the Key 
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV. 
        // IV should always be the block size, which is by
        // default 16 bytes (128 bit) for Rijndael. 
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size. 
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes. 
        byte[] decryptedData = DecryptString(cipherBytes,
                                             pdb.GetBytes(32), pdb.GetBytes(16));

        // Now we need to turn the resulting byte array into a string. 
        // A common mistake would be to use an Encoding class for that.
        // It does not work 
        // because not all byte values can be represented by characters. 
        // We are going to be using Base64 encoding that is 
        // designed exactly for what we are trying to do. 
        return Encoding.Unicode.GetString(decryptedData);
    }

    // Encrypt a byte array into a byte array using a key and an IV 
    private static byte[] EncryptString(byte[] clearData, byte[] Key, byte[] IV)
    {
        // Create a MemoryStream to accept the encrypted bytes 
        var ms = new MemoryStream();

        // Create a symmetric algorithm. 
        // We are going to use Rijndael because it is strong and
        // available on all platforms. 
        // You can use other algorithms, to do so substitute the
        // next line with something like 
        //      TripleDES alg = TripleDES.Create(); 
        Rijndael alg = Rijndael.Create();

        // Now set the key and the IV. 
        // We need the IV (Initialization Vector) because
        // the algorithm is operating in its default 
        // mode called CBC (Cipher Block Chaining).
        // The IV is XORed with the first block (8 byte) 
        // of the data before it is encrypted, and then each
        // encrypted block is XORed with the 
        // following block of plaintext.
        // This is done to make encryption more secure. 

        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure. 
        alg.Key = Key;
        alg.IV = IV;

        // Create a CryptoStream through which we are going to be
        // pumping our data. 
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream and the output will be written
        // in the MemoryStream we have provided. 
        var cs = new CryptoStream(ms,
                                  alg.CreateEncryptor(), CryptoStreamMode.Write);

        // Write the data and make it do the encryption 
        cs.Write(clearData, 0, clearData.Length);

        // Close the crypto stream (or do FlushFinalBlock). 
        // This will tell it that we have done our encryption and
        // there is no more data coming in, 
        // and it is now a good time to apply the padding and
        // finalize the encryption process. 
        cs.FlushFinalBlock();

        // Now get the encrypted data from the MemoryStream.
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way. 
        byte[] encryptedData = ms.ToArray();

        return encryptedData;
    }

    private static byte[] DecryptString(byte[] cipherData,
                                        byte[] Key, byte[] IV)
    {
        // Create a MemoryStream that is going to accept the
        // decrypted bytes 
        var ms = new MemoryStream();

        // Create a symmetric algorithm. 
        // We are going to use Rijndael because it is strong and
        // available on all platforms. 
        // You can use other algorithms, to do so substitute the next
        // line with something like 
        //     TripleDES alg = TripleDES.Create(); 
        Rijndael alg = Rijndael.Create();

        // Now set the key and the IV. 
        // We need the IV (Initialization Vector) because the algorithm
        // is operating in its default 
        // mode called CBC (Cipher Block Chaining). The IV is XORed with
        // the first block (8 byte) 
        // of the data after it is decrypted, and then each decrypted
        // block is XORed with the previous 
        // cipher block. This is done to make encryption more secure. 
        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure. 
        alg.Key = Key;
        alg.IV = IV;

        // Create a CryptoStream through which we are going to be
        // pumping our data. 
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream 
        // and the output will be written in the MemoryStream
        // we have provided. 
        var cs = new CryptoStream(ms,
                                  alg.CreateDecryptor(), CryptoStreamMode.Write);

        // Write the data and make it do the decryption 
        cs.Write(cipherData, 0, cipherData.Length);

        // Close the crypto stream (or do FlushFinalBlock). 
        // This will tell it that we have done our decryption
        // and there is no more data coming in, 
        // and it is now a good time to remove the padding
        // and finalize the decryption process. 
        cs.FlushFinalBlock();

        // Now get the decrypted data from the MemoryStream. 
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way. 
        byte[] decryptedData = ms.ToArray();

        return decryptedData;
    }
非常感谢:)
PS:我从网上抓取了这段代码,并对其进行了一些编辑,以适应我的程序

您需要通过异常,以便诊断发生了什么。为此,只需将解密端设置为不需要填充。这会让它接受任何东西。一旦这样做了,您就可以查看解密过程中出现的问题,并开始诊断故障。请注意,这不是一个解决方案,而是一种忽略异常的方法。导致异常的原因仍然存在

看看出现了什么。都是垃圾吗?部分是垃圾,部分是原始明文?如果是混合的,垃圾在哪里出现:在开始,结束时,两者,在某处的中间?告诉我们你们看到了什么,我们可以给你们指出问题的可能原因


当一切正常时,将加密和解密都设置为PKCS#7填充。不要将“无填充”保留在适当的位置。

您需要通过异常,以便能够诊断发生了什么。为此,只需将解密端设置为不需要填充。这会让它接受任何东西。一旦这样做了,您就可以查看解密过程中出现的问题,并开始诊断故障。请注意,这不是一个解决方案,而是一种忽略异常的方法。导致异常的原因仍然存在

看看出现了什么。都是垃圾吗?部分是垃圾,部分是原始明文?如果是混合的,垃圾在哪里出现:在开始,结束时,两者,在某处的中间?告诉我们你们看到了什么,我们可以给你们指出问题的可能原因


当一切正常时,将加密和解密都设置为PKCS#7填充。不要将无填充保留在适当的位置。

Hey thanx等待答复。.好的,我将尝试您告诉的步骤,并再次查看发生了什么(y)thanx:)hi,使用
填充模式。无
它提供正确的输出。但如何使这项工作与填充。根据您的建议,填充是必要的ryt?如果明文不是整数字节,则需要填充。只需显式地将加密和解密的填充设置为PKCS7(或PKCS5)。编辑为时已晚:“如果纯文本不是整数块,则需要填充。”okey thanx我将尝试..正在解密和加密的字符串也包含阿拉法特字符、数字和特殊字符。Hey thanx回答..okey我将尝试您告诉的步骤,并再次查看发生了什么(y)thanx:)嗨,使用
PaddingMode.None
可提供正确的输出。但如何使这项工作与填充。根据您的建议,填充是必要的ryt?如果明文不是整数字节,则需要填充。只需显式地将加密和解密的填充设置为PKCS7(或PKCS5)。编辑为时已晚:“如果纯文本不是整块数,则需要填充。”okey thanx我将尝试..正在解密和加密的字符串还包含阿拉法特字符、数字和特殊字符。