1

我一直在研究在 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());
        }
    }
}
4

2 回答 2

2

至少对于加密功能,您将CryptoStreamand 的顺序错误。BinaryWriter您当前正在加密您的 IV,而 IV 应该放在密文前面,明文。

IV 在加密前与纯文本进行异或运算。现在,这意味着您将纯文本归零:您正在加密一个零值块。

于 2013-08-23T00:39:17.623 回答
0

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

于 2017-08-17T05:15:02.193 回答