c# – 对称加密(AES):保存加密数据的IV和Salt是否安全正确?

使用对称加密算法(在这种情况下为AES)加密和解密数据时,我正在尝试理解如何处理和管理启动向量和盐(当适用时)。

我从不同的SO线程和各种其他网站推断出,IV或盐都不需要秘密,只有独特的,以防止诸如暴力攻击的密码分析攻击。考虑到这一点,我认为将伪随机IV存储在加密数据中是可行的。我问我正在使用的方法是否正确,此外,我应该以同样的方式对待我目前的硬编码盐吗?那就是把它写在IV边的记忆流中

我的代码:

private const ushort ITERATIONS = 300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22,  0x3c };

private static byte[] CreateKey(string password, int keySize)
{
    DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
    return derivedKey.GetBytes(keySize >> 3);
}

public static byte[] Encrypt(byte[] data, string password)
{
    byte[] encryptedData = null;
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.GenerateIV();
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;

        using (MemoryStream memStream = new MemoryStream(data.Length))
        {
            memStream.Write(provider.IV, 0, 16);
            using (ICryptoTransform encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                }
            }
            encryptedData = memStream.ToArray();
        }
    }
    return encryptedData;
}

public static byte[] Decrypt(byte[] data, string password)
{
    byte[] decryptedData = new byte[data.Length];
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;
        using (MemoryStream memStream = new MemoryStream(data))
        {
            byte[] iv = new byte[16];
            memStream.Read(iv, 0, 16);
            using (ICryptoTransform decryptor = provider.CreateDecryptor(provider.Key, iv))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                {
                    cryptoStream.Read(decryptedData, 0, decryptedData.Length);
                }
            }
        }
    }
    return decryptedData;
}

关于正确的实践,我也可以看到有关对称加密的任何其他信息。

最佳答案
用密码存储IV和Salt很长时间是适当的,也是最佳做法。硬编码盐是没有用的,随机是重要的,硬编码迭代是完全可以的,但通常远高于300(实际上至少1000,如果您的机器/使用可以处理它,通常会高出10秒数千)。

因为我已经看到这么多坏的(或旧的)c#加密的例子从堆栈溢出切割并粘贴到开放源代码中,我写了一个剪切和粘贴加密代码Modern Examples of Symmetric Authenticated Encryption of a string.,我试图保持最新和审查。它将iv和salt与密文一起存储,它还验证密文中包含的密文和值。

理想情况下,一个更好的做法是使用一个高级加密库来处理像iv这样的最佳实践,但是对于csharp来说通常是不存在的。我一直在谷歌的keyczar图书馆的csharp version年工作。虽然它在功能上可以使用,我一直想在第一次官方稳定版本之前更多地关注代码。

转载注明原文:c# – 对称加密(AES):保存加密数据的IV和Salt是否安全正确? - 代码日志