Rfc2898DeriveBytes的输出取决于什么以及如何处理盐?

时间:2017-04-06 10:31:51

标签: c# cryptography salt pbkdf2

public string Encrypt(string Code)
{
    string result = string.Empty;
    byte[] encryptResult = null;
    var CodeInByte = Encoding.ASCII.GetBytes(Code);

    try
    {
        using (MemoryStream memo = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = KeySize;
                AES.BlockSize = BlockSize;

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

                AES.Mode = CipherMode.CBC;

                using (var encrypt = new CryptoStream(memo, AES.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    encrypt.Write(CodeInByte, 0, CodeInByte.Length);
                    encrypt.Close();
                }

                encryptResult = memo.ToArray();
            }
        }

        result = Convert.ToBase64String(encryptResult);
        return result;
    }
    catch (Exception err)
    {
        MsgCode = 99;
        MsgDesc = err.Message;
        return string.Empty;
    }            
}

它只是一个简单的AES加密方法,来自字符串

我想在生成密钥时询问,

var key = new Rfc2898DeriveBytes(CodeInByte, salt, 1000);

是从输入字符串生成的密钥,还是一个随机生成的字节数组?

并且,盐是否需要是静态的

1 个答案:

答案 0 :(得分:3)

正如documentation on MSDN所暗示的那样:

  

Rfc2898DeriveBytes获取密码,salt和迭代计数,然后通过调用GetBytes方法生成密钥。

换句话说,它将使用您提供的输入参数派生字节。如果给它不同的参数,派生的键将是不同的。如果你给它相同的参数,它将生成相同的字节。

对称加密算法(如AES)需要一个固定长度的密钥 - 在这种情况下为AES128需要16个字节。但是,您不希望强制密码是固定长度的,因为这使它们更容易攻击。您可能还需要比可行密码长得多的密钥 - 例如,AES256需要32字节密钥。最后,密码往往是字母数字,可能有一些符号,而加密密钥由字节组成,范围从0x00-0xFF,如果你使加密密钥为32个字符的ASCII密码,那么你会减少范围因为可打印的ASCII字符范围远小于0x00-0xFF。

出于这个原因,您希望从给定密码中获取加密密钥,以便获得所需长度的强密钥。这就是Rfc2898DeriveBytes的用武之地。