我正在做一个项目。加密工作正常,但是当涉及到解密时,我的程序正在抛出错误的数据异常"。我该如何解决这个问题?
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);
}
}
}
答案 0 :(得分:3)
在其他问题中,您假设密文可以有意义地转换为UTF-8,并且无法保证。
如果您想加密文本并将加密内容作为文本传输/存储,您需要遵循以下模式:
加密(textIn => textOut):
textOut = Convert.ToBase64String(bytesOut)
)。解密(textIn => textOut):
Convert.FromBase64String
。使用UTF-8(或ASCII或UCS-2等)进行加密数据的文本表示的问题是加密数据可合法地包含值为0x00
的字节(或控制代码) ,linebreak等)。虽然.NET在很大程度上很乐意在字符串中传输嵌入的空字符,但它肯定会成为混淆的一个重要来源(而且并非所有语言/函数都能处理它)。
其他有趣的角色:
0x7F
(删除)的作用是什么?0x13
(^ S)的Unix命令行可能会挂起,但它只是等待0x11
(^ Q)。用于存储密文的编码是什么?好吧,任何安全打包控制字符的东西。
答案 1 :(得分:1)
假设您的密钥对是正确的,问题是您使用不同的padding schemes进行加密和解密。
传递给RSACryptoServiceProvider#Encrypt
和RSACryptoServiceProvider#Decrypt
的第二个参数表示是否使用OAEP。在加密期间,您正在请求OAEP,但在解密期间,您正在请求PKCS#1 v1.5填充。那些是不兼容的。只需使用更安全的OAEP。
你应该使用
decrypted = rsa.Decrypt(encrypted, true);