2016-04-11 56 views
2

RSAの暗号化と復号化に関する作業中です。この割り当てのためには、のANYサイズキーを暗号化および復号化できる必要があります。C#で複数のブロックをRSA暗号化/復号化する

キーが最大キーサイズを超えないため、暗号化と復号化に成功したコードを作成しましたが、このコードを変更してサイズを変更する必要があります。これISN任意のサイズを復号化するために

//store dataLength 
     int dataLength = dataToEncrypt.Length; 

     //Check if dataLength > 117 
     if (dataLength > 117) 
     { 
      //Divide dataLength by 128 to determine how many cycles will be needed 
      float 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(); 
      } 

し、次のコード:

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 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); 
    } 
} 

私は(私の知識に動作しているようです)任意のサイズを暗号化できるようにするには、次のコードが出ています「T WORKING

float 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); 
     } 

次の行:var decryptedBytes = myRSA.Decrypt(dataByte, false);

でエラーが発生します:An unhandled exception of type 'System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll Additional information: Bad Data.

私はこのエラーがスローされている理由が分からない、私はプログラムをデバッグしているとdataByteに格納されたデータは、[]とき、私の内部に格納されていたものとは何が違うのではないようです最大鍵サイズよりも小さいサイズのメッセージを正常に復号化する。

+0

私の回答はあなたの問題の解決に役立ちましたか?あなたがそれを解決したら、あなたは働くコードであなた自身の答えを掲示し、[受諾](http://meta.stackexchange.com/q/5234/266187)のいずれかの答えに答えることができます。 –

答えて

1

RSAは、非対称暗号システムとして、AESのような対称暗号に比べて実際には遅いです。これを実装する適切な方法は、対称AESキーを生成し、AESで実際のデータを暗号化し(例えば、CBC/CTR/GCM/EAXで)、RSAで単一キーを暗号化することです。

RSAを複数のブロックに適用する標準はないため、実装することはお勧めしません。それでも実装したい場合は、コードにいくつかの問題があります。

RSAはセキュリティ保護のために埋め込みが必要です。 128バイトのキーを使用しており、平文を117バイトブロックに分割しているので、これはPKCS#1 v1.5パディングを使用していることを意味します。各ブロックはパディングされ、暗号化されます。暗号文はモジュラスよりも数値的に厳密に小さいが、通常はかなり近い。ほとんどの暗号文は128バイトになりますが、暗号文は先頭にゼロを格納する必要のないシリアライズされた番号であるため、一部の暗号文は128バイトになります。それは、あなたが単に順番にそれらを書き込むことはできず、それらを正しく読み戻すことを期待できないことを意味します。
暗号文をすべて同じ長さ(128バイト)になるように0x00バイトでパディングするか、または読み取る必要があるかを知るために対応する暗号文の前に各暗号文の長さを格納する必要があります。

関連する問題