解密异常-要解密的数据长度无效 [英] Decryption Exception - length of the data to decrypt is invalid
问题描述
我正在使用C#应用程序.我们有将数据存储在文件上的通用方法.这些方法对数据进行加密并将其存储在文件系统上.当我们需要数据时,ReadData方法将数据解密并返回纯文本.
I am working in a C# application. We have common methods to store data on a file. These methods encrypt the data and store them on the file system. when we need the data, ReadData method decrypts the data and returns me plain text.
如果文本大小较小,则此代码在正常情况下可以正常工作.但是对于下面给出的示例文本,解密代码引发异常-要解密的数据长度无效.
This code works fine in normal cases if size of the text in small. but for a example text given below, the decryption code is throwing exception - length of the data to decrypt is invalid.
该异常发生在行
// close the CryptoStream
x_cryptostream.Close();
我尝试了不同的方法,但是没有运气.可以帮忙吗?
I tried different ways but no luck. Can some pls help.
为什么要加密已经加密的数据-我只是试图使用大型应用程序的通用方法将其存储在文件中.常用方法 storedata(key,data)
nad readdata(key)
进行我无法避免的加密/解密.
Why am I encrypting already encrypted data - I am just trying to store in a file using common method of the huge application. The common methods storedata(key,data)
nad readdata(key)
do the encryption/decryption I can't avoid.
public static byte[] Decrypt(byte[] ciphertext, string Key, string IV)
{
byte[] k = Encoding.Default.GetBytes(Key);
byte[] iv = Encoding.Default.GetBytes(IV);
// create the encryption algorithm
SymmetricAlgorithm x_alg = SymmetricAlgorithm.Create("Rijndael");
x_alg.Padding = PaddingMode.PKCS7;
// create an ICryptoTransform that can be used to decrypt data
ICryptoTransform x_decryptor = x_alg.CreateDecryptor(k, iv);
// create the memory stream
MemoryStream x_memory_stream = new MemoryStream();
// create the CryptoStream that ties together the MemoryStream and the
// ICryptostream
CryptoStream x_cryptostream = new CryptoStream(x_memory_stream,
x_decryptor, CryptoStreamMode.Write);
// write the ciphertext out to the cryptostream
x_cryptostream.Write(ciphertext, 0, ciphertext.Length);
// close the CryptoStream
x_cryptostream.Close();
// get the plaintext from the MemoryStream
byte[] x_plaintext = x_memory_stream.ToArray();
下面是加密方法的代码.
Below is the code of encrypt method.
public static byte[] Encrypt(string strplain, string Key, string IV)
{
byte[] k = Encoding.Default.GetBytes(Key);
byte[] iv = Encoding.Default.GetBytes(IV);
byte[] plaintext = Encoding.Default.GetBytes(strplain);
// create the encryption algorithm
SymmetricAlgorithm x_alg = SymmetricAlgorithm.Create("Rijndael");
x_alg.Padding = PaddingMode.PKCS7;
// create an ICryptoTransform that can be used to encrypt data
ICryptoTransform x_encryptor = x_alg.CreateEncryptor(k, iv);
// create the memory stream
MemoryStream x_memory_stream = new MemoryStream();
// create the CryptoStream that ties together the MemoryStream and
// the ICryptostream
CryptoStream x_cryptostream = new CryptoStream(x_memory_stream,
x_encryptor, CryptoStreamMode.Write);
// write the plaintext out to the cryptostream
x_cryptostream.Write(plaintext, 0, plaintext.Length);
// close the CryptoStream
x_cryptostream.Close();
// get the ciphertext from the MemoryStream
byte[] x_ciphertext = x_memory_stream.ToArray();
// close memory stream
x_memory_stream.Close();
// convert from array to string
string cipher_Tx = Encoding.Default.GetString(x_ciphertext,
0, x_ciphertext.Length);
x_encryptor.Dispose();
x_alg.Clear();
byte[] cipher = Encoding.Default.GetBytes(cipher_Tx);
return cipher;
}
推荐答案
您的问题是 string cipher_Tx = Encoding.Default.GetString(x_ciphertext,0,x_ciphertext.Length);
.
x_ciphertext
不是文本的有效字节表示形式,它具有许多无法表示的字符,并且当您将 byte []
转换为 string
时您正在丢失信息.正确的方法是使用一种字符串格式,该字符串格式旨在使用 Convert.FromBase64String(string)
.
x_ciphertext
is not a valid byte representation of text, it has many unpresentable characters and when you do your byte[]
to string
conversion you are loosing information. The correct way to do it is use a string format that is designed to represent binary data using something like Convert.ToBase64String(byte[])
and Convert.FromBase64String(string)
.
string cipher_Tx = Convert.ToBase64String(x_ciphertext)
x_encryptor.Dispose();
x_alg.Clear();
byte[] cipher = Convert.FromBase64String(cipher_Tx)
话虽如此,您的代码还有很多其他奇怪"的事情,例如您不使用 using
语句,而您确实应该这样做.同样,完全不需要完全转换为字符串并返回,只需返回 x_ciphertext
.代码也可能存在其他问题(例如 Key
和 IV
的字符串从何而来)和许多其他最佳实践(例如您应该生成随机IV并将其写到输出中,并且应该使用密钥派生函数(不是直接来自用户文本)来生成密钥),但是在发现字符串转换问题后,我停止了检查.
That being said, there is a lot of other "odd" things about your code, for example you don't use using
statements and you really should. Also that whole conversion to string and back is totally unnecessary, just return x_ciphertext
. There may be other problems with the code too (like where did the strings for Key
and IV
come from) and many other best practices (like you should be generating a random IV and writing it out in to the output and the key should be generated using a key derivation function not straight from user text), but I stopped checking after I found the string conversion issue.
这篇关于解密异常-要解密的数据长度无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!