解密异常-要解密的数据长度无效 [英] Decryption Exception - length of the data to decrypt is invalid

查看:77
本文介绍了解密异常-要解密的数据长度无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

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