我的AES Intitialization Vectors似乎对C#中的AESCryptoServiceProvider无效

时间:2013-08-22 19:33:39

标签: c# encryption aescryptoserviceprovider

我一直在研究在C#中使用AESCryptoServiceProvider。到目前为止,我有一个似乎有效的实现。但是,我对初始化向量的理解是,当有效负载和密钥相同时,它应该保护我的密文不一样,但看起来我做错了。改变我的初始化向量似乎根本不会影响这些函数的结果。

以下是我的功能:

public string EncryptString(string toEncrypt, byte[] encryptionKey, byte[] iv)
{
    var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt);
    using (var aes = new AesCryptoServiceProvider())
    {
        aes.Key = encryptionKey;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        //aes.GenerateIV();
        aes.IV = iv;

        using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV))
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            using (var bWriter = new BinaryWriter(cs))
            {
                bWriter.Write(aes.IV, 0, aes.IV.Length);
                bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                cs.FlushFinalBlock();
            }
            return Convert.ToBase64String(ms.ToArray());
        }
    }
}

public string DecryptString(string toDecrypt, byte[] encryptionKey, byte[] iv)
{
    using (var aes = new AesCryptoServiceProvider())
    {
        aes.Key = encryptionKey;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        var toDecryptBytes = Convert.FromBase64String(toDecrypt);

        Array.Copy(toDecryptBytes, 0, iv, 0, iv.Length);
        aes.IV = iv;

        using (var ms = new MemoryStream())
        {
             using (var cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, iv), CryptoStreamMode.Write))
             using (var binWriter = new BinaryWriter(cs))
             {
                 binWriter.Write(toDecryptBytes, iv.Length, toDecryptBytes.Length - iv.Length);
             }
             return Encoding.Default.GetString(ms.ToArray());
        }
    }
}

我的加密功能的新版本我现在已经遵循@owlstead的建议,改回了CBC模式。现在使用CBC似乎正常工作。

public string EncryptString(string toEncrypt, byte[] encryptionKey)
{
    var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt);
    using (var aes = new AesCryptoServiceProvider())
    {
        aes.Key = encryptionKey;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        aes.GenerateIV();

        using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV))
        using (var ms = new MemoryStream())
        {
             ms.Write(aes.IV, 0, aes.IV.Length);
             using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
             using (var bWriter = new BinaryWriter(cs))
             {
                 bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                 cs.FlushFinalBlock();
             }
             return Convert.ToBase64String(ms.ToArray());
        }
    }
}

2 个答案:

答案 0 :(得分:2)

至少在加密函数中,您将CryptoStreamBinaryWriter置于错误的顺序。您目前正在加密您的IV,而IV应该放在密文的前面。

在加密之前,IV与纯文本进行异或。现在,这意味着您将纯文本清零:您正在加密零值块。

答案 1 :(得分:0)

CipherMode.ECB模式似乎没有拿起IV参数(这意味着无论你输入什么IV,结果都是一样的),这是可能的,因为ECB不需要一个概念作为初始向量,因为那里也没有后续的载体。如果要屏蔽ECB块,请在加密正常之前手动对块进行异或。 当您更改为CipherMode.CBC时,IV确实很重要,因为后续块将与之前的加密块进行异或,形成一个链。