RSA解密过程中的错误数据异常 [英] Bad Data exception during RSA decryption
问题描述
using System;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用System.Text;
使用System.IO;
使用System.Security.Cryptography;
命名空间WindowsFormsApplication2
{
public partial class Form1:Form
{
byte [] cipher;
byte [] plain;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender,EventArgs e)
{
}
private静态字符串加密(byte [] plain)
{
byte [] encrypted;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
StreamReader StRe = new StreamReader(D:\\\PjesaVetemPublike.xml);
string VetemPublikeXML = StRe.ReadToEnd();
rsa.FromXmlString(VetemPublikeXML);
StRe.Close();
encrypted = rsa.Encrypt(plain,true);
return Encoding.UTF8.GetString(encrypted);
}
private static string Decrypt(byte [] encrypted)
{
byte [] decryptpted;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
StreamReader StRe = new
StreamReader(D:\\PjesaPublikeDhePrivate.xml);
string PublikeDhePrivate = StRe.ReadToEnd();
rsa.FromXmlString(PublikeDhePrivate);
StRe.Close();
decryptpted = rsa.Decrypt(encrypted,false); // THE ERROR APPEARS RIGHT HERE
return Encoding.UTF8.GetString(decryptpted);
}
private void button1_Click(object sender,EventArgs e)
{
plain = Encoding.UTF8.GetBytes(txtPlain.Text);
txtCipher.Text = Encrypt(plain);
}
private void button2_Click(object sender,EventArgs e)
{
txtDekriptuar.Text = Decrypt(cipher);
}
}
}
除了其他问题,您假定密文可以有意义地转换为UTF-8,这是不能保证的。
如果要加密文本并将加密的内容作为您需要遵循以下模式的文本进行传输/存储:
加密(textIn => textOut):
- 通过一些编码将textIn转换为bytesIn。 UTF-8是相当不错的。
- 将bytesIn加密到bytesOut。
- 对bytesOut应用无损编码。 Base64几乎总是最好的选择,而且是.NET内置的最好的选择。 (
textOut = Convert.ToBase64String(bytesOut)
)。 - 返回textOut。
解密(textIn => textOut):
- 应用加密的逆变换来打开textIn到字节很可能
Convert.FromBase64String
。 - 将bytesIn解密到bytesOut。
- 应用文本编码转换为将byteOut转换为textOut。没有什么是真的说这需要与加密中使用的一样,但这可能是有道理的。
对加密数据的文本表示使用UTF-8(或ASCII或UCS-2等)的问题是加密数据可以合法地包含一个值为$ code> 0x00 (或控制代码,换行符等)。虽然.NET,在大多数情况下,快乐地将嵌入的空字符传输到字符串中,但绝对可能是一个很大的混乱来源(并不是所有的语言/函数都处理相同)。
其他有趣的角色:
- 您的语言/功能对嵌入式
0x7F
(删除)? - 如果将字符串存储在单行文本字段中,CR或LF字符会发生什么?您的程序在Windows上如果获得没有LF的CR或没有CR的LF,那么您的程序在Windows上执行什么?
- 具有
0x13的Unix命令行
(^ S)可能会挂起,但只是等待0x11
(^ Q)。
什么编码用于存储密文?嗯,任何安全地包装控制字符的东西。
- Base64:存储增加33%:3个字节=> 4个ASCII字符== 4个字节
- 十六进制(又名Base16):存储增加100%,但比Base64更容易检查
- 其他较不常见的选项总结在 https://en.wikipedia.org/wiki/Binary-to-text_encoding#Encoding_standards 。
I was working on a project. Encryption is working fine but when it comes to decryption my program is throwing "Bad data Exception". How do I remedy this problem?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
byte[] cipher;
byte[] plain;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private static string Encrypt(byte[] plain)
{
byte[] encrypted;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
StreamReader StRe = new StreamReader("D:\\PjesaVetemPublike.xml");
string VetemPublikeXML = StRe.ReadToEnd();
rsa.FromXmlString(VetemPublikeXML);
StRe.Close();
encrypted = rsa.Encrypt(plain, true);
return Encoding.UTF8.GetString(encrypted);
}
private static string Decrypt(byte[] encrypted)
{
byte[] decrypted;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
StreamReader StRe = new
StreamReader("D:\\PjesaPublikeDhePrivate.xml");
string PublikeDhePrivate = StRe.ReadToEnd();
rsa.FromXmlString(PublikeDhePrivate);
StRe.Close();
decrypted = rsa.Decrypt(encrypted, false); //THE ERROR APPEARS RIGHT HERE
return Encoding.UTF8.GetString(decrypted);
}
private void button1_Click(object sender, EventArgs e)
{
plain = Encoding.UTF8.GetBytes(txtPlain.Text);
txtCipher.Text = Encrypt(plain);
}
private void button2_Click(object sender, EventArgs e)
{
txtDekriptuar.Text = Decrypt(cipher);
}
}
}
Among other problems you are assuming that the ciphertext can be converted to UTF-8 meaningfully, and that isn't guaranteed.
If you want to encrypt text and transmit/store the encrypted contents as text you need to follow this pattern:
Encrypt(textIn => textOut):
- Convert textIn to bytesIn via some encoding. UTF-8 is pretty good.
- Encrypt bytesIn to bytesOut.
- Apply a lossless encoding to bytesOut. Base64 is almost always the best choice for this, and is the best one that's built in to .NET. (
textOut = Convert.ToBase64String(bytesOut)
). - Return textOut.
Decrypt(textIn => textOut):
- Apply the inverse transform from Encrypt to turn textIn to bytesIn. So likely
Convert.FromBase64String
. - Decrypt bytesIn to bytesOut.
- Apply a text encoding transform to turn bytesOut to textOut. There's nothing that really says that this needs to be the same as the one used in Encrypt, but it probably makes sense to do so.
The problem with using UTF-8 (or ASCII or UCS-2, etc) for a textual representation of encrypted data is that the encrypted data can legitimately contain a byte whose value is 0x00
(or a control code, linebreak, etc). While .NET, for the most part, happily transports embedded null characters in a string it definitely can be a large source of confusion (and not all languages/functions handle it the same).
Other fun characters:
- What does your language/function do for an embedded
0x7F
(Delete)? - If you store the string in a single-line text field, what happens to any CR or LF characters? What does your program do on Windows if it gets CR without LF, or LF without CR?
- A Unix command-line with
0x13
(^S) may appear to hang, but it's just waiting on0x11
(^Q).
What encodings to use for storing ciphertext? Well, anything that safely packs control characters.
- Base64: 33% increase in storage: 3 bytes => 4 ASCII characters == 4 bytes
- Hexadecimal (aka Base16): 100% increase in storage, but easier to inspect than Base64
- Other, less common options are summarized at https://en.wikipedia.org/wiki/Binary-to-text_encoding#Encoding_standards.
这篇关于RSA解密过程中的错误数据异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!