填充无效,无法使用Rijndael删除

时间:2015-06-18 14:20:15

标签: c# encryption rijndael

当我使用此代码进行加密和解密时,我收到了错误

填充无效,无法删除。

任何想法

public static class Crypto
{

    private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");

    // This constant is used to determine the keysize of the encryption algorithm.
    private const int keysize = 256;

    public static string Encrypt(string plainText, string passPhrase)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            byte[] cipherTextBytes = memoryStream.ToArray();
                            return Convert.ToBase64String(cipherTextBytes);
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText, string passPhrase)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我使用你的方法尝试了以下方法,它运行良好:

var passPhrase = "123456";
var e = Encrypt("testtesttesttest", passPhrase);
Console.WriteLine(e); // YEtSJshcn686ZO+JlEQ48ap/odhuvIGalbAT1XhinqQ=
var d = Decrypt(e, passPhrase);
Console.WriteLine(d); // testtesttesttest

这表明您要么将passPhrase传递给Decrypt()到您传递给Encrypt()的{​​{1}},要么在解密之前以某种方式破坏密文。 (您是否可以使用密文和密码参数调用Decrypt来调用?)

还值得注意的是,代码顶部注释中的所有内容都是错误的:

  • 将任何盐传递给PasswordDeriveBytes
  • IV的大小必须等于块大小(16字节),它与使用的密钥大小无关。
  • 将{16}字符串传递给Encoding.ASCII.GetBytes()会产生16字节输出, 32字节。 (这恰巧巧合地意味着你的initVectorBytes实际上是IV的正确长度。

此外,PasswordDeriveBytes已弃用,不应使用。你应该使用Rfc2898DeriveBytes代替,你应该使用适当的盐值。 IV也不应该是静态值,绝对不是从ASCII字符串派生的值!