2013 年的哈希身份验证数据


Hashing authentication data in 2013

我面临着永无止境的问题如何在数据库中存储密码?.据我最近读到的,有一些以前被认为是安全的算法,这些算法被标记为不安全。所以我正在努力寻找一个最新的资源来描述那些不再安全的资源。

我正在考虑组合两个或三个算法,但我记得当时它被认为是不安全的,即将哈希暴露在攻击之下。我想到的组合是这样的:

data_h1 = sha256(sha1(data_salt).sha1([username|email]).sha1(data_peper))
data_h2 = sha256(sha1(data_salt).sha1(user_entered_password).sha1(data_pepper))
hmac(
sha512,
data,
sha512(general_salt.data_h1.data_h2.general_pepper)
);

其中data_saltdata_pepper是常量,硬编码到应用程序中,但与general_salt和general_pepper不同,后者也是硬编码常量。[用户名|电子邮件] 是用户在注册和登录时提供的值,以及 *user_entered_password* (doh!(。

  1. 这会以某种方式损害安全性吗?(如果没有,请转到下一步(
  2. 在生成过程中,由于哈希狂热,是否会有重大瓶颈?(转到下一步(
  3. 对上述方法有什么建议吗?

我的问题适用于 PHP,但很高兴看到你们会推荐什么以及您的评论一般是什么,b'cuz 我确实认为这是非常常见的任务,许多人仍然只使用 MD5 或 SHA1(或者更好的是,以纯文本形式存储(。

不单独使用 SHA-1 或 SHA-256 进行哈希密码的主要原因是相对而言,它们速度很快。密码身份验证容易受到字典攻击攻击和暴力攻击,因为用户倾向于在其密码中包含常用词并使用相对较短的密码,使其比加密密钥更容易猜测。

建议使用 bcrypt 和 PBKDF2 等哈希函数,因为它们很慢。它们可以调整为几乎任何时间;它应该需要很长时间可以在不造成不合理延迟的情况下对密码进行哈希处理。这将有助于减缓字典攻击和暴力攻击。

但是,这不是密码存储的唯一安全注意事项。

当"存储"密码时,您实际上并不存储密码,而是存储其单向哈希。 这样做的原因是防止甚至有权访问系统的人学习用户的密码。 哈希的"单向"方面意味着,虽然可以从明文创建哈希,但不可能从哈希中学习明文。

此外,所有密码在散列之前都应与盐(随机数字序列(连接。 salt 值应与哈希一起存储在数据库中。 盐必须是特定于行的,即每个密码都应该有自己的盐。

为什么哈希必须特定于行? 想象一下,黑客以某种方式获得了您的数据库的副本。 通常,他要面对的是一个相当大的蛮力任务。 如果您只有一个哈希,黑客可以检查所有行并找到出现频率最高的行,因为相同的密码 + 相同的盐总是呈现相同的哈希。 因此,通过这些信息,他可以猜测这些行包含常用密码。 然后,他可以使用这些信息来减小暴力问题的大小。 或者,他可以尝试学习其中一个用户的密码,然后能够在具有相同哈希的任何其他用户帐户上使用该密码。 盐的全部意义在于防止这种性质的攻击。

使用带有用户特定盐的体面的单向加密安全哈希。 这是存储密码的标准方法。

添加特定于应用程序的"pepper"(每行都相同,并且必须是加密随机的并保存在安全位置(将哈希转换为 HMAC(基于哈希的消息身份验证代码(,这甚至更好。 如果有人知道你的哈希算法和盐,但不知道胡椒,他将很难猜测密码。

相关文章: