2016-12-12 58 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

谢谢!它像一个魅力! –