2016-04-10 40 views
0

您好Stackoverflow用戶,我正在做有關RSA加密和解密的任務,並且遇到了一個棘手的問題。C#問題使用RSA解密來解密

使用Visual Studio我創建了一個帶有2個文本框(一個用於顯示純文本消息,另一個用於顯示加密的消息)和4個按鈕(2個清除按鈕來清除相應的文本框以及加密按鈕和解密按鈕)。

public partial class Form1 : Form 
{ 
    //Strings to hold public & private keys 
    String publicKey, privateKey; 
    UnicodeEncoding encoder = new UnicodeEncoding(); 

    public Form1() 
    { 
     RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider(); 
     InitializeComponent(); 
     privateKey = myRSA.ToXmlString(true); 
     publicKey = myRSA.ToXmlString(false); 
    } 

    private void btnClr1_Click(object sender, EventArgs e) 
    { 
     txtPlain.Text = ""; 
     txtPlain.Refresh(); 
    } 

    private void btnClr2_Click(object sender, EventArgs e) 
    { 
     txtCypher.Text = ""; 
     txtCypher.Refresh(); 
    } 

    private void btnEncrypt_Click(object sender, EventArgs e) 
    { 
     var myRSA = new RSACryptoServiceProvider(); 

     //Set cryptoserviceprovider with the proper key 
     myRSA.FromXmlString(publicKey); 

     //Encode the data to encrypt as a byte array 
     var dataToEncrypt = encoder.GetBytes(txtPlain.Text); 

     //Encrypt the byte array 
     var encryptedByteArray = myRSA.Encrypt(dataToEncrypt, false).ToArray(); 

     var length = encryptedByteArray.Count(); 
     var item = 0; 
     var sb = new StringBuilder(); 

     //Change each byte in the encrypted byte array to text 
     foreach(var x in encryptedByteArray) 
     { 
      item++; 
      sb.Append(x); 
      if (item < length) sb.Append(","); 
     } 
     txtCypher.Text = sb.ToString(); 
    } 

    private void btnDecrypt_Click(object sender, EventArgs e) 
    { 
     var myRSA = new RSACryptoServiceProvider(); 

     //Split data into an array 
     var dataArray = txtCypher.Text.Split(new char[] { ',' }); 

     //Convert chars to bytes 
     byte[] dataByte = new byte[dataArray.Length]; 

     for(int i = 0; i < dataArray.Length; i++) dataByte[i] = Convert.ToByte(dataArray[i]); 

     //Decrypt the byte array 
     myRSA.FromXmlString(privateKey); 
     var decryptedBytes = myRSA.Decrypt(dataByte, false); 

     //place into cypher text box 
     txtPlain.Text = encoder.GetString(decryptedBytes); 
    } 
} 

我對加密和解密消息沒有任何問題(只要它們顯然不超過RSA密鑰大小)。

因此,我正在努力修改我的程序,以允許對任何大小的消息進行加密和解密。

這是代碼,我拿出來讓任何大小進行加密(這似乎工作)

private void btnEncrypt_Click(object sender, EventArgs e) 
    { 
     var myRSA = new RSACryptoServiceProvider(); 

     //Set cryptoserviceprovider with the proper key 
     myRSA.FromXmlString(publicKey); 

     //Encode the data to encrypt as a byte array 
     var dataToEncrypt = encoder.GetBytes(txtPlain.Text); 

     //store dataLength 
     int dataLength = dataToEncrypt.Length; 

     //Check if dataLength > 128 
     if (dataLength > 128) 
     { 
      //Divide dataLength by 128 to determine how many cycles will be needed 
      double numOfCycles = (dataLength/117); 
      //round up to nearest whole number 
      cycles = (int)Math.Ceiling(numOfCycles); 


      //for however many cycles 
      for (int i = 0; i < cycles; i++) 
      { 
       var myByteArray = new byte[117]; 
       for (int j = 0; j < 117; j++) 
       { 
        int currentByte = i * 117 + j; 
        myByteArray[j] = dataToEncrypt[currentByte]; 
       } 

       var encryptedByteArray = myRSA.Encrypt(myByteArray, false).ToArray(); 

       var length = encryptedByteArray.Count(); 
       var item = 0; 

       //Change each byte in the encrypted byte array to text 
       foreach (var x in encryptedByteArray) 
       { 
        item++; 
        sb.Append(x); 
        if (item < length) sb.Append(","); 
       } 
       txtCypher.Text = sb.ToString(); 
      } 
     } 
     else 
     { 
      var encryptedByteArray = myRSA.Encrypt(dataToEncrypt, false).ToArray(); 
      var length = encryptedByteArray.Count(); 
      var item = 0; 
      var sb = new StringBuilder(); 

      //Change each byte in the encrypted byte array to text 
      foreach(var x in encryptedByteArray) 
      { 
       item++; 
       sb.Append(x); 
      if (item < length) sb.Append(","); 
      } 
       txtCypher.Text = sb.ToString(); 
      } 
    } 

這是我拿出來處理任何解密代碼尺寸信息(這是什麼,是給我的錯誤)

private void btnDecrypt_Click(object sender, EventArgs e) 
    { 
     var myRSA = new RSACryptoServiceProvider(); 

     //Split data into an array 
     var dataArray = txtCypher.Text.Split(new char[] { ',' }); 

     int length = dataArray.Count(); 
     float numOfCycles = (length/117); 
     int cycles = (int)Math.Ceiling(numOfCycles); 

     for (int i = 0; i < cycles; i++) 
     { 
      byte[] dataByte = new byte[117]; 
      for(int j = 0; j < 117; j++) 
      { 
       //Convert chars to bytes 
       dataByte[j] = Convert.ToByte(dataArray[ i * 117 + j ]); 
      } 
      //Decrypt the byte array 
      myRSA.FromXmlString(privateKey); 
      var decryptedBytes = myRSA.Decrypt(dataByte, false); 
      txtPlain.Text += encoder.GetString(decryptedBytes); 
     } 
    } 

的錯誤,它被拋出是:

`System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll. Additional information: Bad Data.` 

from line 133:var decryptedBytes = myRSA.Decrypt(dataByte, false);

任何幫助/建議將不勝感激!謝謝大家!

+0

RSA不應該用於多於大致鍵位的位。如果您需要加密大量數據,請生成一次性AES密鑰並使用RSA對其進行加密。 –

回答

0

正如Luke Park所說的,嘗試使RSA成爲鏈式算法通常被認爲是不好的做法。它的目的是爲了安全的「密鑰交換」,這意味着加密內容被認爲是對稱加密信息。

但是,如果你決心走下這條路,問題在於RSA-Encrypt總是產生一個長度爲密鑰大小的輸出。您的代碼在=> 117個字節時假設117個字節;而事實並非如此。因爲你沒有給它一個有效的數據報(一個有效的長度等於密鑰大小),因爲RSA-Decrypt希望你已經準備好了使用RSA-Encrypt的數據,所以它報告「壞數據」。