当前位置: 首页 > 知识库问答 >
问题:

使用Rfc2898DeriveBytes在C#中用胡椒和盐散列密码

壤驷鸿
2023-03-14

我想在C#中使用PBKDF2加胡椒和盐来散列密码。我对密码学有点陌生,所以如果我错了,请随时纠正我。

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

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

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

  • 示例:(密码输入(?)胡椒粉(16字节)盐(16字节)

我的代码

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);
    }
}

我理解:

  • 散列是不可逆的

研究:微软Rfc2898DeriveBytes,示例代码

共有2个答案

归和惬
2023-03-14
  1. 输入大于输出大小不是问题。一个好的散列函数应该能够抵抗所有攻击,即使输入非常大
  2. 说到好的散列函数:20字节的输出大小暗示正在使用SHA-1。SHA-1已损坏,实际碰撞已经存在,因此不应使用。(我不知道如果SHA-1存在冲突,Rfc2898是否是一个安全的方案,但在安全性方面,一个方案比抱歉方案更安全。
  3. 除此之外,实现似乎还可以。我不是最新的C语言,但您似乎正在为salt使用加密RNG。
  4. 你也应该是随机的。
  5. 128位(16字节)密钥完全可以,只要您的密码不需要在50年左右的时间内保持安全
凌长恨
2023-03-14

PBKDF2(与SHA-1)-可怕的名称为Rfc2898DeriveBytes实现-使用重复的HMAC,密码编码为字节-作为密钥。一般来说,HMAC只是在输入键上执行填充方法(如果你想查找ipad和opad)。这个填充会增加到哈希函数的输入块大小。然而,让我们看看HMAC RFC中HMAC的定义:

我们用B表示这些块的字节长度(对于所有上述哈希函数示例,B=64),并用L表示哈希输出的字节长度(对于MD5,L=16,对于SHA-1,L=20)。认证密钥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)。

我理解:

哦,天哪;)

  • 哈希是不可逆的。

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

  • 加入盐和胡椒以增加安全性并防止彩虹桌攻击。

你只需要一点盐就可以了。如果密码可以保持安全并且足够强大,胡椒粉可以防止攻击者完全猜到密码。

  • salt是一个唯一的随机字符串,它不必是秘密的,可以与散列一起存储在数据库中

没错。

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

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

  • 至少128位(16字节

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

注意,在SHA-1需要另一个块加密之前,PBKDF2的salt配置选项的大小可以是64-8-4=52字节。因为这个原因,盐

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

现在我们通常推荐大约一百万个。但实际上,你可以节省的任何CPU周期都会让对手更难对付。当然,如果对手真的拿不到胡椒,这一点就有点没有意义了。在这种情况下,一轮就足够了——但是您可能希望使用更高的迭代计数作为第二道防线(例如,针对试图使用数据库副本获取用户密码的系统管理员)。

 类似资料:
  • 注意:为了讨论的目的,假设应用程序和数据库存储在单独的机器上,不共享密码等。因此数据库服务器的破坏并不自动意味着应用程序服务器的破坏。

  • 我模拟存储密码散列,并在登录过程中验证它。 我有一个名为的方法来获取字符串密码,并通过添加盐返回它的哈希值。 我选择一个静态值,在本例中,我选择一个相同的密码值() 但结果是: 为什么这两个值不相同? 我的代码有什么问题?

  • 问题内容: 我想知道在带有OpenCV的Python或任何其他向图像添加高斯噪声或椒盐噪声的python图像处理库中是否存在某些函数?例如,在MATLAB中,存在直接功能可以完成相同的工作。 或者,如何使用带有OpenCV的Python向图像添加噪点? 问题答案: 该功能会在图像中添加高斯,椒盐,泊松和斑点噪声

  • 我试图学习密码学,用散列和盐析在数据库中保存密码,所以我决定做一个登录系统来实现这个系统。 我的数据库包括 UserID int PK 用户名varchar(250) Salt varbinary(64) 密码varbinary(64) RegDate日期时间 电子邮件varchar(250) 我正在使用PBKDF2,但似乎这不是散列/盐析方法,如果不是呢? 如果是这样,我做得对吗? 我的钥匙 将

  • 问题内容: 我正在开发一个小型的Web应用程序,该应用程序在内部对用户进行身份验证。一旦用户通过身份验证,我的Web应用程序便会将一些信息(例如userID和Person的名称)传递给第三方Web应用程序。第三方开发人员建议我们对值进行哈希处理和加盐处理。 原谅我的无知,但这到底意味着什么? 我正在用Java编写应用程序。因此,我打算做的是使用Apache Commons Digest Utils

  • 我用这个教程来帮助我,当用户创建一个帐户时,对他们的密码进行加盐和散列,然后当用户输入密码登录时,将这些密码带回来并进行比较。 在这个图坦卡蒙中,它们有两个我想调用的函数。 和 我随后自己创建了另一个函数,它会爆炸结果,因此我可以从整个have中剥离加盐字符串。 所以当我在数据库中插入数据时,它看起来像这样 请注意,最后一列包含第三列中字符串的最后一部分。 因此,最后一步是登录时,用户将输入他们的