-1

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

我正在考虑结合两个或三个算法,但我记得在那天它被认为是不安全的,即将散列暴露给攻击。我想到的组合是这样的:

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,它们也是硬编码的常量。[username|email]是用户在注册和登录时提供的值,以及 *user_entered_pa​​ssword* (doh!)。

  1. 这会以某种方式损害安全性吗?(如果没有转到下一个)
  2. 由于在生成过程中将发生的 hash-o-mania 是否会出现重大瓶颈?(转到下一个)
  3. 关于上述方法的任何建议?

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

4

2 回答 2

4

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

推荐使用像 和 PBKDF2 这样的散列函数bcrypt,因为它们很。它们可以被调整为花费几乎任何时间;在不造成不合理延迟的情况下,应该尽可能长时间地对密码进行哈希处理。这将有助于减缓字典攻击和蛮力攻击。

然而,这并不是密码存储的唯一安全考虑。

于 2013-10-06T01:33:19.613 回答
1

在“存储”密码时,您实际上并没有存储密码,而是存储了它的单向哈希。这样做的原因是为了防止即使是有权访问系统的人也无法获知用户的密码。散列的“单向”方面意味着,虽然可以从明文创建散列,但不可能从散列中学习明文。

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

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

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

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

于 2013-10-08T02:59:39.103 回答