加密和解密填充不够好

时间:2016-12-12 20:15:41

标签: c# visual-studio encryption

我使用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位它总是有效,所以我真的不知道该怎么做。我感谢任何反馈。

1 个答案:

答案 0 :(得分: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;
  }