2017-06-06 76 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))。 –