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我将尝试..正在解密和加密的字符串还包含阿拉法特字符、数字和特殊字符。