【问题标题】:Hashing a password with pepper and salt in C# using Rfc2898DeriveBytes使用 Rfc2898DeriveBytes 在 C# 中使用胡椒和盐对密码进行哈希处理
【发布时间】:2019-12-13 12:19:48
【问题描述】:

我想在 C# 中使用带有胡椒和盐的 PBKDF2 对密码进行哈希处理。我对密码学有点陌生,如果我错了,请随时纠正我。

我使用 Rfc2898DeriveBytes 类是因为(根据其他 Stackoverflow 用户)bcrypt 和其他哈希算法在 C# 中不受本机支持和验证,因此它可能构成安全威胁。这篇文章的目的不是开始讨论哪种散列算法是最好的。 > Bcrypt in C# Stackoverflow

我的目标: 每个密码都会得到一个随机的盐和胡椒,密码会经过一定的迭代次数。

我的问题:与所需的哈希大小相比,输入大小更大是否不好,我的实现是否正确?

  • 示例:(PasswordInput (?) + Pepper(16 字节)+ Salt(16 字节)> HashOutput(20 字节)

我的代码

public class GenerateHash
{
    //Fields
    private const int saltSize = 16;
    private const int hashSize = 16;
    private const int iterations = 10000;
    private const string secretPepper = "Secret 16 Byte pepper."; 

   //Properties
    private string inputId { get; set; }

    //Methods
    public byte[] GeneratePBKDF2String(string inputId, string secretPepper, int saltSize, int 
    hashSize, int iterations)
    {
        // Generate a random salt.
        RNGCryptoServiceProvider cryptographicServiceProvider = new RNGCryptoServiceProvider();
        byte[] salt = new byte[saltSize];
        provider.GetBytes(salt);

        // Generate a salted hash with pepper.
        Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(inputId + secretPepper, salt, iterations);
        return pbkdf2.GetBytes(hashSize);
    }
}

我明白:

  • 哈希是不可逆的。
  • 添加了盐和胡椒以提高安全性并防止彩虹桌攻击。
  • 盐是一个唯一且随机的字符串,它不必保密,可以与哈希一起存储在数据库中。
  • 辣椒不是唯一的,它用于每个哈希。这是一个秘密,不存储在数据库中。
  • 至少应使用 128 位(16 个字节 > 16 个字符)来表示盐和胡椒。
  • 算法应至少使用 10.000 次迭代。

研究: Microsoft Rfc2898DeriveBytes, Example Code

【问题讨论】:

    标签: c# cryptography pbkdf2


    【解决方案1】:

    PBKDF2(带有 SHA-1)——被称为 Rfc2898DeriveBytes 的可怕实现——使用重复的 HMAC 和密码 - 编码为字节 - 作为密钥。通常,HMAC 只是对输入键执行填充方法(如果要查找,则为 ipad 和 opad)。此填充上升到散列函数的输入块大小。不过,让我们看一下 HMAC RFC 中 HMAC 的定义:

    我们用 B 表示这样的字节长度 块(对于所有上述哈希函数示例,B=64), L 是散列输出的字节长度(对于 MD5,L=16,对于 MD5,L=20 SHA-1)。认证密钥 K 可以是任意长度,最长为 B,即 哈希函数的块长度。 使用密钥时间更长的应用程序 比 B 字节将首先使用 H 散列密钥,然后使用 生成的 L 字节字符串作为 HMAC 的实际密钥。

    在您的情况下,如果您的编码密码长于 64 - 16 = 48 字节(辣椒大小为 16),您的 HMAC 可能会更慢。 然而,智能 PBKDF2 函数可以检测到这一点并通过只执行一次初始哈希部分来解决问题。

    因此,如果您的密码超过 48 字节,那么您可以在以下情况下为攻击者带来一些好处:

    1. 你的实现不是那么聪明和
    2. 攻击者的实现聪明的。

    请注意,哈希输出大小与此无关。您可以将 PBKDF2 与 SHA-512 一起使用——块大小为 1024 位,而不是 SHA-1 和 SHA-256 的 512 位——以防出现问题。

    如果您请求的字节数超过输出大小,则 PBKDF2(默认为 SHA-1)中的哈希函数的哈希输出大小很重要。在这种情况下,您也将优势交还给攻击者。幸运的是,您只要求 hashSize 中的 16 个字节(您可能希望将变量名称更改为 passwordHashSize 以避免混淆)。


    我明白:

    亲爱的;)

    • 哈希是不可逆的。

    密码散列函数和密码散列函数不可逆,其他散列函数可能是可逆的。

    • 添加了盐和胡椒以提高安全性并防止彩虹桌攻击。

    你只需要一个盐。辣椒可以防止攻击者完全猜出密码,如果它可以保持安全并且足够强大。

    • 盐是一个唯一且随机的字符串,它不必保密,可以与哈希一起存储在数据库中。

    没错。

    • 辣椒不是唯一的,它用于每个哈希。这是一个秘密,不存储在数据库中。

    或者它本身被加密并存储在数据库中,但是是的,最终它需要以一种或另一种方式保护。

    • 至少应使用 128 位(16 个字节 > 16 个字符)来表示盐和胡椒。

    嗯,这是一种上限,我会说 64 到 128 个完全随机位,最好超过 80 个。但是,并不是每个字符都可以映射到一个字节,所以你的辣椒不太可能是完全随机的 -对于基本上是密钥的东西来说,这是一个坏主意。

    请注意,在 SHA-1 需要另一个块加密之前,PBKDF2 的 salt 配置选项可以是最大 64 - 8 - 4 = 52 字节的任意大小。出于这个原因,盐和胡椒通常是串联的。这也将允许您使用真正的随机辣椒。这样也可以为密码留下更多字符 (64)。

    • 算法应至少使用 10.000 次迭代。

    现在我们通常推荐大约一百万。但实际上,您可以节省的任何数量的 CPU 周期都会使对手更难对付。如果对手真的当然无法获得成功,那么这一点就没有实际意义了。在这种情况下,一轮就足够了 - 但您可能希望使用更高的迭代次数作为第二道防线(例如,防止系统管理员尝试使用数据库副本获取用户的密码)。

    【讨论】:

      【解决方案2】:
      1. 输入大于输出大小不是问题。一个好的哈希函数应该能抵抗所有的攻击,即使输入真的很大。
      2. 谈到好的散列函数:20 字节的输出大小暗示正在使用 SHA-1。 SHA-1 已损坏,实际冲突已经存在,因此不应使用。 (我不知道 Rfc2898 在是否存在 SHA-1 冲突的情况下是否是安全的方案,但在安全性方面,安全总比后悔好。
      3. 否则执行似乎没问题。我不是最新的 C#,但您似乎正在使用加密 RNG 作为盐。
      4. 你的辣椒也应该是随机的。
      5. 128 位(16 字节)密钥完全可以,只要您的密码不需要安全保存超过 50 年左右。

      【讨论】:

      • Rfc2898 使用 HMAC-SHA1,我不知道这是否会使实现更加安全。 Rfc2898 可以配置为具有更多的迭代,但它的弱点在于它可以很容易地通过使用小内存的专用硬件进行暴力破解,与最终攻击者相比,防御者的成本更高。 Scrypt 解决了这个问题,因为它需要更多的内存。 Argon2 也是基于此原则构建的,但不幸的是,Microsoft 并未在 C# 中对其进行验证(据我所知。)如果它们在 C# 中得到验证,我很想听听替代方案。
      • HMAC-Construction 允许使用已经损坏的方案(即使 HMAC-md5 也是安全的 AFAIK),但使用完整的算法肯定感觉更好。虽然我不知道它是否经过验证,但似乎有一个用于官方 Argon2 c 实现的 C# 绑定github.com/alipha/csharp-argon2
      猜你喜欢
      • 2011-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 2019-04-24
      相关资源
      最近更新 更多