2016-12-12 86 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) 
     { 

     } 
    } 
} 

這段代碼的問題是,每當我嘗試運行它,我總是得到:

輸入不是一個有效的Base-64字符串,因爲它含有非基礎64個字符,多於兩個填充字符或填充字符中的非法字符。

我該怎麼辦?如果我嘗試取出+ Encrypt.EncryptString位,它總是有效,所以我真的不知道該怎麼做。我很欣賞任何反饋。

+0

爲什麼你的'+ Encrypt.EncryptString'位在那裏呢?我想如果你想連接數據,你需要在*之前調用'Convert.ToBase64String',因爲它會附加一個終結符/填充符,每個base-64字符串只能包含一次。無論是或者你需要在解密之前再次將它拆分成多個字符串。 – BlueMonkMN

+0

[加密和解密字符串]的可能重複(http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string) – MethodMan

+0

您使用IV的方式是錯誤的。與上述評論相反,它也與密鑰大小無關。你應該多研究一下。 –

回答

0

每個base64字符串都以0,1或2個=字符結尾,這是base64編碼中的一個特殊字符,只能用於終止字符串。因此,如果您嘗試連接多個base64字符串,則必須在將其轉換爲 base64之前連接數據,或者在轉換 base64之前,必須重新拆分它。終結者每個字符串只能存在一次。

下面是再次解碼之前分割字符串修改的解密處理程序:

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

謝謝!它像一個魅力! –