问题描述
我正在使用 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)
和 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.ToBase64String(byte[])
和 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.
这篇关于解密异常 - 要解密的数据长度无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!