2016-04-10 43 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的数据,所以它报告“坏数据”。