2017-06-06 150 views
-3

我正在开发一个项目。加密工作正常,但当涉及到解密我的程序正在抛出“坏数据异常”。我该如何解决这个问题?RSA解密期间的数据异常异常

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

这可能是一个坏钥匙的迹象。检查你的密钥 – mjw

回答

3

在其他问题我们假定你是密文可以转换为UTF-8有意义,那就是不能保证。

如果要加密的文本和发送/加密的内容存储为文本,你需要遵循这个模式:

加密(textIn =>的TextOut):通过一些

  • 转换textIn到bytesIn编码。 UTF-8非常好。
  • 加密bytesIn为bytesOut。
  • 对bytesOut应用无损编码。 Base64几乎总是这个的最佳选择,并且是内置于.NET中的最佳选择。 (textOut = Convert.ToBase64String(bytesOut))。
  • 退货textOut。

解密(textIn =>的TextOut):

  • 应用从加密逆变换转textIn到bytesIn。所以可能Convert.FromBase64String
  • 解密bytesIn到bytesOut。
  • 应用文本编码转换将bytesOut转为textOut。没有什么真的说这需要与Encrypt中使用的相同,但这样做可能是有意义的。

使用UTF-8(或ASCII或UCS-2,等等),用于加密数据的文本表示的是,将加密的数据可以合法地包含(一个字节,其值是0x00或控制代码的问题, linebreak等)。尽管.NET大部分情况下都愉快地在字符串中传输嵌入的空字符,但肯定会造成大量混淆(并非所有的语言/函数都处理它)。

其他有趣的字符:

  • 什么是你的语言/功能的嵌入式0x7F(删除)呢?
  • 如果将字符串存储在单行文本字段中,那么会发生任何CR或LF字符?如果程序在没有LF的情况下获取CR,或者在没有CR的情况下获得LF,那么您的程序在Windows上做了什么
  • 具有0x13(^ S)的Unix命令行可能会挂起,但它只是在等待0x11(^ Q)。

什么编码用于存储密文?那么,任何安全包装控制角色的东西。

+0

它的工作,谢谢。 –

1

假设您的密钥对是正确的,问题是您正在使用不同的padding schemes进行加密和解密。

传递给RSACryptoServiceProvider#EncryptRSACryptoServiceProvider#Decrypt的第二个参数表示是否使用OAEP。在加密期间,您正在请求OAEP,但在解密期间,您正在请求PKCS#1 v1.5填充。那些不兼容。只需使用更安全的OAEP即可。

您应该使用

decrypted = rsa.Decrypt(encrypted, true); 
+0

这就是mscorlib.dll中出现'System.Security.Cryptography.CryptographicException'类型的未处理异常。 附加信息:要解密的数据超过128字节这个模数的最大值。 –

+1

看来您的私钥与您的公钥不兼容。此外,RSA不能用于加密任意数据(您需要实现[混合加密](https://en.wikipedia.org/wiki/Hybrid_cryptosystem))。 –