随着我继续构建越来越多的网站和Web应用程序,我经常被要求以一种方式存储用户的密码,如果/当用户遇到问题时可以检索它们(要么通过电子邮件发送忘记的密码链接,请通过当我能够对抗这种做法时,我会做很多"额外"编程,以便在不存储实际密码的情况下进行密码重置和管理协助.
当我无法抗争(或无法获胜)时,我总是以某种方式对密码进行编码,以至于它至少不会以明文形式存储在数据库中 - 尽管我知道如果我的数据库被黑客攻击破坏密码的罪魁祸首并不需要太多,所以这让我感到不舒服.
在一个完美的世界里,人们经常更新密码,而不是在许多不同的网站上复制密码 - 不幸的是,我知道许多人拥有相同的工作/家庭/电子邮件/银行密码,甚至在需要帮助时自由地给我.如果我的数据库安全程序由于某种原因失败,我不想成为他们的财务终结负责人.
在道德和道德上,我觉得有责任保护一些用户的生活,即使他们以较少的尊重对待他们.我确信有许多途径可以用来腌制哈希和不同的编码选项,但是当你必须存储它们时,是否有一个"最佳实践"?在几乎所有情况下,我都使用PHP和MySQL,如果这对我应该处理细节的方式有任何不同.
附加信息Bounty
我想澄清一点,我知道这不是你想要做的事情,在大多数情况下拒绝这样做是最好的.但是,我并不是在寻找关于采取这种方法的优点的演讲我正在寻找采取这种方法时采取的最佳步骤.
在下面的一个注释中,我指出,当人们被要求执行安全的密码恢复程序时,主要针对老年人,智障人士或非常年轻人的网站可能会让人感到困惑.虽然在这些情况下我们可能会发现它简单而平凡,但有些用户需要额外的帮助,要么让服务技术人员帮助他们进入系统,要么将其直接通过电子邮件发送/显示给他们.
在这样的系统中,如果用户没有获得这种级别的访问协助,那么来自这些人口统计数据的流失率可能会阻碍应用程序,因此请记住这样的设置.
谢谢大家
这是一个有趣的问题,有很多争论,我很喜欢它.最后,我选择了一个保留密码安全性的答案(我不必保留纯文本或可恢复的密码),但也使我指定的用户群可以登录到系统而没有我从中找到的主要缺点正常的密码恢复.
由于不同的原因,我一直有大约5个答案,但我必须选择最好的答案 - 所有其他答案都是+1.感谢大家!
此外,感谢Stack社区中的每个人都投票赞成这个问题和/或将其标记为最喜欢的.我以100票赞成票作为赞美,并希望这次讨论能够帮助其他与我有同样关切的人.
更新:请注意我不是在询问盐是什么,彩虹表是什么,字典攻击是什么,或盐的目的是什么.我在查询:如果你知道用户的salt和hash,那么计算密码是不是很容易?
我理解这个过程,并在我的一些项目中自己实现它.
s = random salt
storedPassword = sha1(password + s)
Run Code Online (Sandbox Code Playgroud)
在您存储的数据库中:
username | hashed_password | salt
Run Code Online (Sandbox Code Playgroud)
我所看到的盐析的每次实施都会在密码的末尾添加盐,或者开始:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
Run Code Online (Sandbox Code Playgroud)
因此,来自黑客的字典攻击是值得他的盐(哈哈),只需针对上面列出的常见组合中存储的盐运行每个关键字.
当然,上述实现只是为黑客增加了另一个步骤,而没有真正解决潜在的问题?有什么替代方法可以解决这个问题,还是我误解了这个问题?
我唯一能想到的就是有一个秘密混合算法,它以随机模式将salt和密码绑定在一起,或者将其他用户字段添加到散列过程中,这意味着黑客必须能够访问数据库和代码才能获得花边他们为字典攻击证明富有成效.(更新,正如评论中指出的那样,最好假设黑客可以访问您的所有信息,因此这可能不是最好的).
让我举一个例子,说明我如何建议黑客用密码和哈希列表来破解用户数据库:
来自我们黑客数据库的数据:
RawPassword (not stored) | Hashed | Salt
--------------------------------------------------------
letmein WEFLS... WEFOJFOFO...
Run Code Online (Sandbox Code Playgroud)
通用密码字典:
Common Password
--------------
letmein
12345
...
Run Code Online (Sandbox Code Playgroud)
对于每个用户记录,循环公共密码并对其进行哈希:
for each user in hacked_DB
salt = users_salt
hashed_pw = users_hashed_password
for each common_password
testhash = sha1(common_password + salt)
if testhash = hashed_pw then
//Match! Users password …Run Code Online (Sandbox Code Playgroud) 我继承了一个Web应用程序,我刚刚在SQL Server数据库中以纯文本形式存储了超过300,000个用户名/密码.我意识到这是一件非常糟糕的事情.
知道我必须更新登录和密码更新过程以加密/解密,并且对系统其余部分的影响最小,您会建议从数据库中删除纯文本密码的最佳方法是什么?
任何帮助表示赞赏.
编辑:对不起,如果我不清楚,我打算问你的加密/哈希密码的程序,而不是特定的加密/散列方法.
我应该只是:
我想我的关注更多来自于大量的用户,所以我想确保我正确地做到这一点.