2016-12-12 7 views
-1

私はRijndaels暗号化方式を使用して文字列の入力を暗号化しました。ここに私のコードは次のとおりです。暗号化と復号化のパディングが十分でない

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.IO; 
using System.Threading; 
using System.Security.Cryptography; 
using System.Windows.Forms; 

namespace WindowsFormsApplication5 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     public string plainText; 

     private void textBox1_TextChanged(object sender, EventArgs e) 
     { 

     } 

     public static class Encrypt 
     { 
      // This size of the IV (in bytes) must = (keysize/8). Default keysize is 256, so the IV must be 
      // 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array. 
      private const string initVector = "pemgail9uzpgzl88"; 
      // This constant is used to determine the keysize of the encryption algorithm 
      private const int keysize = 256; 
      //Encrypt 
      public static string EncryptString(string plainText, string passPhrase) 
      { 
       byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector); 
       byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); 
       PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); 
       byte[] keyBytes = password.GetBytes(keysize/8); 
       RijndaelManaged symmetricKey = new RijndaelManaged(); 
       symmetricKey.Mode = CipherMode.CBC; 
       ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); 
       MemoryStream memoryStream = new MemoryStream(); 
       CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); 
       cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
       cryptoStream.FlushFinalBlock(); 
       byte[] cipherTextBytes = memoryStream.ToArray(); 
       memoryStream.Close(); 
       cryptoStream.Close(); 
       return Convert.ToBase64String(cipherTextBytes); 
      } 
      //Decrypt 
      public static string DecryptString(string cipherText, string passPhrase) 
      { 
       byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); 
       byte[] cipherTextBytes = Convert.FromBase64String(cipherText); 
       PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); 
       byte[] keyBytes = password.GetBytes(keysize/8); 
       RijndaelManaged symmetricKey = new RijndaelManaged(); 
       symmetricKey.Mode = CipherMode.CBC; 
       ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); 
       MemoryStream memoryStream = new MemoryStream(cipherTextBytes); 
       CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); 
       byte[] plainTextBytes = new byte[cipherTextBytes.Length]; 
       int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 
       memoryStream.Close(); 
       cryptoStream.Close(); 
       return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
      } 
     } 

     public string encryptedText; 

     private void button1_Click(object sender, EventArgs e) 
     { 
      string key = "a"; 
      plainText = textBox1.Text; 
      encryptedText = plainText; 
      encryptedText = Encrypt.EncryptString(plainText, key) + Encrypt.EncryptString(plainText, key); 
      textBox1.Text = encryptedText; 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      string key = "a"; 
      encryptedText = Encrypt.DecryptString(encryptedText, key) + Encrypt.DecryptString(encryptedText, key); 
      encryptedText = plainText; 
      textBox1.Text = plainText; 
     } 

     private void openFileDialog(object sender, EventArgs e) 
     { 

     } 
    } 
} 

このコードの問題は、私はそれを実行しようとするたびに、私は常に取得することです:

それは非塩基を含むように、入力が有効なベース-64文字列ではありません64文字、2つ以上のパディング文字、またはパディング文字の間に不正な文字が含まれている可能性があります。

どうすればよいですか? + Encrypt.EncryptStringビットを取り出そうとすると、常に動作するので、何をすべきか分からない。私はフィードバックを感謝します。

+0

:ここ

は再びそれらを復号化する前の文字列を分割修正復号化ハンドラですか?データを連結したい場合は、* Convert.ToBase64String'を呼び出す前に*これを行う必要があると思うでしょう。これは、base-64文字列ごとに一度しか含まれないターミネーター/パディングを追加するためです。それを解読する前に複数の文字列に分割する必要があります。 – BlueMonkMN

+0

[文字列を暗号化して解読する]の可能な複製(0120-17753) – MethodMan

+0

IVを使用する方法は間違っています。上記のコメントに反して、キーサイズとは何の関係もありません。これをもう少し調べてください。 –

答えて

0

すべてのbase64文字列は0、1、または2 =文字で終了します。これは、文字列を終了するためにのみ使用できるbase64エンコーディングの特殊文字です。したがって、複数のbase64文字列を連結しようとする場合は、 base64に変換する前にデータを連結するか、 base64に変換する前に分割する必要があります。ターミネータは文字列ごとに1つしか存在できません。あなたがそこに `+ Encrypt.EncryptString`ビットを持っていないのはなぜ

private void button2_Click(object sender, EventArgs e) 
    { 
    string key = "a"; 
    int startPos = 0; 
    StringBuilder decrypted = new StringBuilder(); 
    do 
    { 
     int endPos = encryptedText.IndexOf('=', startPos); 
     if ((encryptedText.Length > endPos + 1) && encryptedText[endPos + 1] == '=') 
      endPos++; 
     string decrypt = encryptedText.Substring(startPos, endPos - startPos + 1); 
     decrypted.Append(Encrypt.DecryptString(decrypt, key)); 
     startPos = endPos+1; 
    } while ((startPos > 0) && (startPos < encryptedText.Length)); 
    plainText = decrypted.ToString(); 
    textBox1.Text = plainText; 
    } 
+0

または等号がゼロです。 –

+0

ありがとう!それは魅力のように機能します! –