【问题标题】:Web Application - Storing a PasswordWeb 应用程序 - 存储密码
【发布时间】:2011-09-21 19:43:04
【问题描述】:

我错过了什么吗?是否有任何额外的步骤将密码存储到数据库?

存储密码:
在对该主题进行尽可能多的研究之后,我得出的结论是,将用户密码存储在 Web 应用程序数据库(在我的情况下为 MySQL+PHP)中的最佳方法如下:

  • 分配站点范围的静态盐。 (16 个 rand 字符,包括 0-9、a-z、A-Z、[]/*-')
  • 为每个用户分配一个随机盐(存储在数据库中)。
  • 存储结果 hash_function($userPassword + $sitewideSalt + $randomSalt)
  • 将 $randomSalt 存储在生成的哈希旁边。
  • 使用 bcrypt 可调工作负载 散列

  • 攻击 #1: 攻击者通过 SQL 注入转储数据库。
    数据库结果 我们的 hash_function 和随机数 用户盐。

    在转储之后,攻击者可以 获取 $userPassword$randomSalt 通过查找他自己的帐户。然后通过猜测哈希 诸如md5之类的功能他可以启动一个 彩虹攻击 $sitewideSalt。但这可能需要高达 1.41 亿 世纪[1]。

    通过使用这种类型的安全性不允许 DB 转储危及存储的密码。用户仍然需要通过其他方法找到 $sitewideSalt

  • 攻击 #2: 攻击者找到本地文件包含 (LFI) 向量。
    攻击者可以获得我们 Web 应用程序的原始代码。

    通过可能的 LFI 利用 Web 应用程序后 或 RFI[2] 攻击者读取 我们网站的源代码 应用程序并获得我们的简单 算法和存储的
    $sitewideSalt


下一步要去哪里?
现在攻击者拥有了两种盐,他可以开始使用彩虹来获取实际密码。除了他必须为每个用户制作 1 个彩虹表 ,因为每个用户都有不同的随机用户特定盐 ($randomSalt)。

"现代服务器可以计算 MD5 每秒大约 330MB 的哈希值。如果 您的用户的密码是 小写、字母数字和 6 字符长,你可以尝试每一个 该大小的单个可能密码 大约 40 秒。”
“...CUDA,您可以组建自己的小型超级计算机集群,让您每秒尝试大约 700,000,000 个密码...”[3]

    我们现在需要做的是通过使用诸如 bcrypt 之类的耗时算法来扩展散列函数。 bcrypt 的工作负载因子可以是简单散列函数的 5-6 个数量级。破解一个密码可能需要数年而不是几分钟。作为奖励,bcrypt 已经为每个散列生成了一个随机盐,并将其存储在生成的散列中。

  1. http://www.grc.com/haystack.htm
  2. http://www.wildcardsecurity.com/security101/index.php?title=Local_File_Inclusion

【问题讨论】:

    标签: passwords security hash salt


    【解决方案1】:

    干得好!对我来说看起来很完整。

    我唯一的建议是:

    轮换服务盐。

    设计一种方法来定期轮换服务范围的盐,并定期执行。

    例如,在生成新的服务 salt 后,将其用于所有新帐户和任何密码更改。当现有用户尝试登录时,使用旧服务盐对他们进行身份验证。如果成功,则使用新的服务盐(以及可选的新用户特定盐)更新其哈希。对于“一段时间”未登录的用户,代表他们随机生成一个新密码。这将为放弃您网站的用户“保持”安全性,迫使那些返回的用户使用密码重置工具。 (“某个时间”=您喜欢的任何时期)。

    不要硬编码你的服务盐。

    不要让 LFI 攻击损害您的服务盐。在启动时将服务盐提供给您的应用程序,并将其保存在内存中。要破坏服务盐,攻击者需要能够执行代码以从内存中读取盐。如果攻击者可以做到这一点,那么无论如何你都很好。 =)

    不要重复使用用户的盐。

    寻找机会为用户提供新盐。用户更改密码?生成一个新的随机盐。如果攻击者能够随时获取他的哈希值,这将进一步阻碍暴力破解您的服务器范围的盐。再加上定期轮换你的服务盐,我敢打赌你对暴力破解有很强的威慑力。

    (如果其他人有其他想法,请将其标记为社区 wiki)。

    【讨论】:

    • 我有点困惑。服务盐的逻辑如何用于身份验证?我猜我在 mysql 中存储了一个服务盐,然后在登录时,我将它附加到用户哈希并存储哈希并检查它们是否相等。但是,这和没有服务盐不一样吗?因为如果用户哈希和存储哈希都匹配,那么附加服务盐也将匹配。
    • 为什么需要定期轮换盐?
    【解决方案2】:

    使用 BCrypt 处理密码是唯一的步骤,或者更确切地说,包括以下步骤:

    1. 获取密码,提供给 BCrypt 库。
    2. 存储生成的哈希值。
    3. 将密码与哈希进行比较。

    你也忘记了这个链接:http://codahale.com/how-to-safely-store-a-password/ 这是你引用的引用。

    【讨论】:

      猜你喜欢
      • 2016-07-26
      • 2012-03-06
      • 2010-10-06
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 2010-09-07
      相关资源
      最近更新 更多