AES Padding无法移除

时间:2016-08-08 15:44:36

标签: c# encryption padding

描述

我使用的是稍微修改过的安全类,直接来自codeproject.com,我用它来加密/解密aes字节数组。

我已经测试过,这些密钥生成方法生成相同的密钥,并且它们被赋予相同的密码和盐。他们也有相同的IV

错误总是在CryptoStream.Write函数

AES_Decrypt之后的行上

"未处理的类型' System.Security.Cryptography.CryptographicException'发生在mscorlib.dll

其他信息:填充无效,无法删除。"

(是的,我知道有一个静态盐是坏的,这仅用于测试目的)

无效的解决方案

Paddingmode.Zeros
Paddingmode.None
.FlushFinalBlock();

相关问题

相关链接

代码

using System.Security.Cryptography;
using System.IO;
using System;

namespace FinexCore
{
    public class Security
    {
        /*
         * AES encrypt and decrypt from:
         * http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt 
         */

        // Set your salt here, change it to meet your flavor:
        // The salt bytes must be at least 8 bytes.
        private byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8}; //8 bytes

        public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
        {
            byte[] encryptedBytes = null;

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    AES.Padding = PaddingMode.PKCS7;

                    AES.KeySize = 256;
                    AES.BlockSize = 128;

                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);

                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                        cs.FlushFinalBlock();
                    }
                    encryptedBytes = ms.ToArray();
                }
            }

            return encryptedBytes;
        }

        public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
        {
            byte[] decryptedBytes = null;

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    AES.Padding = PaddingMode.PKCS7;

                    AES.KeySize = 256;
                    AES.BlockSize = 128;

                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                        cs.FlushFinalBlock();
                    }
                    decryptedBytes = ms.ToArray();
                }
            }

            return decryptedBytes;
        }

        public void Wipe()
        {
            Array.Clear(saltBytes, 0, saltBytes.Length);
        }
    }
}

注意:使用完全相同的密码

调用保存和加载函数

调用加密的代码

public void Load(byte[] password)
    {
        Security decryptor = new Security();
        byte[] bytes = decryptor.AES_Decrypt(System.IO.File.ReadAllBytes(Pathname()), password);

        using (MemoryStream stream = new MemoryStream(bytes))
        {
            var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            Root = (Folder)binaryFormatter.Deserialize(stream);
        }
        Array.Clear(bytes, 0, bytes.Length);
        Array.Clear(password, 0, password.Length);
        decryptor.Wipe();
    }

    public void Save(byte[] password)
    {
        byte[] bytes;
        using (MemoryStream stream = new MemoryStream())
        {
            var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            binaryFormatter.Serialize(stream, Root);
            bytes = stream.ToArray();
        }

        Security encryptor = new Security();
        bytes = encryptor.AES_Encrypt(bytes, password);

        System.IO.File.WriteAllBytes(Pathname(), bytes);
        Array.Clear(bytes, 0, bytes.Length);
        Array.Clear(password, 0, password.Length);
        encryptor.Wipe();
    }

测试密钥生成的代码

static void keytests()
{
    byte[] passwordBytes = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    byte[] saltBytes = { 1, 2, 3, 4, 5, 6, 7, 8};
    int iterations = 1000;

    var key1 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, iterations);
    var key2 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, iterations);

    Console.WriteLine(BTS(key1.GetBytes(256 / 8)));
    Console.WriteLine(BTS(key2.GetBytes(256 / 8)));
}

public static string BTS(byte[] ba)
{
    StringBuilder hex = new StringBuilder(ba.Length * 2);
    foreach (byte b in ba)
        hex.AppendFormat("{0:x2}", b);
    return hex.ToString();
}

0 个答案:

没有答案