【问题标题】:Which method of password storage is more secure [closed]哪种密码存储方法更安全[关闭]
【发布时间】:2014-05-17 13:54:39
【问题描述】:

哪种存储密码的方法更安全?我缺乏自己确定答案的数学背景。

为了争论,我们假设为以下每种方法生成的所有密码和用户名都是随机生成的 6 个已知正好是 6 个 alpha-humeric-special-character 字段的字符,并且每个都使用相同的散列算法和相同的传球次数。

  1. 标准方式。用户名以纯文本形式存储,只有密码才能被发现。 Hash(PlaintextPassword + UniqueRecordSalt) = 密码存储在数据库中。

  2. 一个字段被识别为 LoginInfo = Hash(Encryption(UserName, Password) + Shared Salt)。用户名和密码都不会以任何其他格式存储。

用户名/密码组合的强制交叉尝试是否抵消了共享盐而不是唯一记录盐的弱点?这当然是完全忽略了对可用性的所有影响,完全专注于安全性。

由于我缺乏密码学和数学知识来自己得出答案,谁能指点我任何软件来帮助我自己回答这个问题?

请随时将其移至更合适的论坛。我不知道还能把它放在哪里。但是,我不认为这是一个与程序员日常工作无关的话题。

【问题讨论】:

  • 您是在寻找一种方式哈希还是两种方式意味着使用密钥加密并使用该密钥解密?
  • 这个问题似乎是题外话,因为它是关于与存储密码相关的安全性;不是特定的编程问题。
  • @user1096646:正如在下面的答案中所评论的,请查看 security.stackexchange 或 crypto.stackexchange,您会发现此问题之前已解决。

标签: encryption hash passwords


【解决方案1】:

正如您所说,选项 1 是存储密码的标准方式。只要您使用具有唯一盐的安全哈希函数(例如NIST recommend PBKDF2),您的密码就是安全的。所以我会推荐这个选项。

选项 2 没有任何意义。您无法“撤消”散列函数,那么为什么要加密其内容呢?然后,您还必须将加密密钥存储在完全不同的地方。

你所说的共享盐是什么意思?如果你总是使用相同的盐,那么这将破坏你的哈希值。每行唯一的盐是要走的路。

我会说将用户名和密码组合到一个哈希中会使事情变得过于复杂,并且限制了您在开发中的选择,因为您无法从给定用户名的数据库中获取一行。

假设您想在 5 次错误密码尝试后锁定用户。使用标准的纯文本用户名和散列密码,您只需拥有一个“login_attempt_count”列,并在每次输入错误密码时更新该用户的行。

如果您的用户名和密码一起散列,您将无法通过登录尝试计数来识别要更新的行,因为散列的正确用户名和错误密码不会匹配任何散列。 我想您可以使用某种映射函数来获取给定用户名的 row_id,但我会说它只是不必要的复杂,而且越复杂,您就越有可能出现安全漏洞。

正如我所说,我只会选择选项 1。这是存储密码的行业标准方式,并且对于几乎任何应用程序都足够安全(只要您使用现代安全哈希函数)。

【讨论】:

  • PBKDF2 是一种标准的密码散列技术。 SHA-1 不是(除非 SHA-1 是 PBKDF2 使用的本机哈希)。
  • 是的,你是对的,我已经编辑了我的答案。
【解决方案2】:

请先阅读How to securely hash passwords?。总结一下:

  • 切勿使用任何散列算法的单次传递。
  • 永远不要自己滚动,这就是您的示例 2(如果 + 表示连接,示例 1 也是如此)。
  • 用户名明文存储
  • 每个用户生成的盐,8-16 个随机字节,以明文形式存储
    • 纯二进制或编码为 Base64 或十六进制或任何您喜欢的格式。
  • 使用 BCrypt、SCrypt 或 PBKDF2
  • 在预期的未来高峰时间使用尽可能高的工作系数/成本/迭代次数。
  • 特别是对于 PBKDF2,不要要求比本机哈希产生的二进制输出字节多。无论如何,我会说不少于 20 个二进制字节。
    • SHA-1:输出 = 20 个字节(40 个十六进制数字)
    • SHA-224:20 字节
    • SHA-256:20 字节
    • SHA-384:20 个字节
    • SHA-512:20 字节
  • 特别是对于 PBKDF2,SHA-384 和 SHA-512 目前在 64 位系统上具有比较优势,因为 2014 年老式 GPU 的许多攻击者将使用 64 位操作比您的防御系统具有更小的优势CPU 比在 32 位操作上要多。

如果您想要一个示例,请查看PHP source code,尤其是PHP.net Password Hashing FAQ 中的password_hash() 和password_verify() 函数。

另外,我在my github repositories 有各种(目前非常粗略的)密码哈希示例。现在它几乎完全是 PBKDF2,但我将来会添加 BCrypt、SCrypt 等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-03
    • 2017-12-26
    • 2013-05-14
    • 2011-02-03
    • 1970-01-01
    • 2013-01-18
    • 2010-09-16
    • 1970-01-01
    相关资源
    最近更新 更多