处理用户帐户身份验证和密码的最佳方法
什么是在系统中处理用户帐户管理而不让员工有权访问数据库的最佳方法?
例子:
- 在数据库中存储用户名/密码。这是一个坏主意,因为有权访问数据库的任何人都可以看到用户名和密码。因此使用它。
- 存储用户名/密码哈希。这是一种更好的方法,但是可以通过将数据库中的密码哈希替换为我们知道身份验证信息的另一个帐户的哈希来访问该帐户。然后,在授予访问权限后,将其还原回数据库中。
Windows / * nix如何处理此问题?
解决方案
回答
我们可以将散列密码的盐存储在另一个表中,当然每个用户都有自己的盐。然后,我们可以限制对该表的访问。
回答
- 确实是一个非常糟糕的主意。如果数据库遭到破坏,则所有帐户都受到破坏。
- 好方法。如果哈希算法包含用户名,则无法使用另一哈希替换密码哈希。
Unix将哈希存储在文本文件/ etc / shadow中,只有特权用户才能访问该文件。密码用盐加密。
回答
This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for.
真的没有办法解决。具有对密码文件的写访问权的任何人都可以完全控制计算机。
回答
我们可以使用openID,并且完全不保存任何机密用户密码。谁说这仅适用于网站?
回答
我会用2,但要加些盐。一些伪代码:
SetPassword(user, password) salt = RandomString() hash = Hashfunction(salt+password) StoreInDatabase(user, salt, hash) CheckPassword(user, password) (salt, hash) = GetFromDatabase(user) if Hashfunction(salt+password) == hash return "Success" else return "Login Failed"
使用在库中实现的众所周知的哈希函数(例如MD5或者SHA-1)很重要。不要自己动手,也不要尝试从一本书中实现它,这根本不值得把它弄错。
@Brian R. Bondy:我们使用salt的原因是使字典更加困难,攻击者无法对字典进行哈希处理并尝试使用所有密码,相反,她必须对salt +字典进行哈希处理,从而使存储需求激增。如果我们有1000个最常用密码的字典并对其进行哈希处理,则需要16 kB之类的东西,但是如果我们添加两个随机字母,则我们将获得62 * 62 * 16 kB 62 Mb的东西。
另外,我们可以使用某种一次性密码,我听说过有关OTPW的好消息,但还没有使用过。
回答
通常的方法是对电子邮件使用选项二:
将用户名,密码哈希和电子邮件地址存储到数据库中。
用户可以输入密码或者重设密码,在后一种情况下,将生成随机密码,为用户创建一个新的哈希,然后通过电子邮件将密码发送给他。
编辑:如果数据库遭到破坏,那么我们只能保证无法访问任何明智的信息,我们不能再确保应用程序的安全性。
回答
将用户名和密码哈希在一起。这样,如果两个用户使用相同的密码,则哈希将仍然不同。
回答
杰夫·阿特伍德(Jeff Atwood)关于散列的一些不错的文章,如果我们决定走那条路:
- 彩虹哈希开裂
- 我们可能存储的密码不正确
回答
这是多年前在UNIX中常见的问题,通过将用户身份组件(用户名,UID,shell,全名等)与身份验证组件(密码哈希,密码哈希盐)分开来解决。身份组件可以全局读取(如果要将UID映射到用户名,则实际上必须是身份组件),但是身份验证组件必须保持对用户不可访问。要对用户进行身份验证,请拥有一个受信任的系统,该系统将接受用户名和密码,并返回简单的"已认证"或者"未认证"结果。该系统应该是唯一可以访问身份验证数据库的应用程序,并且应该在响应之前等待随机的时间(可能在0.1到3秒之间),以帮助避免定时攻击。
回答
对于许多应用程序来说这不是一个小问题,因为获得数据库访问权限可能是任何攻击者的最常见目标。那么,如果他们已经可以访问数据库了,为什么他们仍然要登录该应用程序? :)
回答
如果"系统"是公共网站,则RPX可以为我们提供最常见的提供商(例如OpenId,Facebook,Google等)的登录/用户帐户服务。
现在,考虑到我们提出问题的方式,我猜我们正在谈论的"系统"很有可能是一个内部基于Windows / Linux的企业应用程序。尽管如此;对于那些搜寻登录/用户帐户提供商的人(就像我在接触RPX之前所做的那样),这可能是一个不错的选择: