解密异常 - 要解密的数据长度无效

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)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.代码也可能存在其他问题(例如 KeyIV 的字符串来自哪里)和许多其他最佳实践(例如您应该生成随机 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.

这篇关于解密异常 - 要解密的数据长度无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)