Passwords Web应用程序-存储密码

Passwords Web应用程序-存储密码,passwords,security,hash,salt,Passwords,Security,Hash,Salt,我错过什么了吗?是否有其他步骤将密码存储到数据库 存储密码: 在对该主题进行了尽可能多的研究之后,我得出结论,在web应用程序数据库(在我的例子中是MySQL+PHP)中存储用户密码的最佳方法如下: 指定站点范围的静态盐。(16兰特字符,包括0-9、a-z、a-z、[]/*-') 为每个用户分配一个随机salt(存储在数据库中) 存储结果散列函数($userPassword+$SiteWideAlt+$randomSalt) 将$randomSalt存储在生成的哈希旁边 使用bcrypt可调工

我错过什么了吗?是否有其他步骤将密码存储到数据库

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

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

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

    在转储之后,攻击者可以 获取$userPassword$salt通过查找他自己的帐户。然后通过猜散列 功能,如md5,他可以启动 彩虹攻击 $sitewideSalt。但这可能需要141亿美元 世纪[1]

    通过使用这种类型的安全性不允许数据库转储破坏存储的密码。用户仍然必须通过另一种方法找到$sitewideSalt

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

    通过可能的LFI开发web应用程序之后 或RFI[2]攻击者读取 我们网站的源代码 应用并得出了我们的简单结论 算法和存储的数据
    $sitewideSalt


下一步该怎么办?
现在,攻击者拥有两种盐,他可以开始获取实际密码。但他必须为每个用户制作一张彩虹表,因为每个用户都有不同的随机用户专用盐($randomSalt)

“现代服务器可以计算MD5 每秒大约330MB的哈希。如果 您的用户拥有以下密码: 小写、字母数字和6 字符长,你可以尝试每一个 该大小的单个可能密码 大约40秒后,“
”…CUDA,你可以组装你自己的小型超级计算机集群,它可以让你每秒尝试70000000个密码……[3]

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


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

  • 获取密码,将其提供给BCrypt库
  • 存储结果哈希
  • 比较密码和散列

  • 您还忘记了这个链接:这是您引用的引用。

    干得好!我觉得很完整

    我唯一的建议是:

    旋转服务盐。

    设计一种方法,定期轮换服务范围内的盐,并定期进行锻炼

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

    不要硬编码您的服务。

    不要让LFI攻击损害您的服务。在启动时将服务盐添加到应用程序中,并将其保存在内存中。要破坏salt服务,攻击者需要能够执行代码从内存中读取salt。如果攻击者能够做到这一点,那么不管怎么说,你都可以很好地使用软管

    不要重复使用用户盐。

    寻找给用户提供新盐的机会。用户是否更改了密码?生成一个新的随机盐。如果攻击者能够在任何时候获得其哈希值,这将进一步妨碍暴力强制您的服务器范围的salt。再加上定期轮换你的服务盐,我敢打赌你对暴力强迫有很强的威慑力


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

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