关于在数据库中存储密码的建议

时间:2009-09-12 13:23:57

标签: sql encryption cryptography oauth passwords

这是情况 - 它与StackOverflow.com上的其他数据库/密码问题略有不同

我有两组用户。一个是“主要”用户。其他人是“次要”用户。每个人都有我的网站的登录名/密码(比如mysite.com - 这并不重要)。

背景:主要用户可以访问第三个站点(例如www.something.com/PrimaryUser1)。每个次要用户“属于”主要用户,并希望访问该其他站点的子部分(例如www.something.com/PrimaryUser1/SecondaryUser1)。

在mysite.com上,主要用户必须向我提供他们用来访问www.something.com/PrimaryUser1的凭据,并指定他们选择的次要用户可以访问哪些“子部分”。

Mysite.com帮助管理次要用户对主用户网站的子访问。次要用户无法“看到”他们的主要用户的密码,但通过我的网站,他们可以访问其他网站的“子部分” - 但仅限于其受限制的子部分。

粗略地说,我正在实施OAuth(或类似的东西)。

这里的问题是 - 我应该如何将主要用户的凭据存储到其他站点?这里的关键点是mysite.com使用这些凭据来提供对次要用户的访问,因此它必须能够读取它。但是,我想以这样的方式存储它,主要用户可以放心,我(作为网站所有者)无法读取他们的凭据。

我认为这更像是一个理论方法问题。密码学世界中有什么东西可以帮助我吗?


添加了文字:

由于大多数人都完全忽略了这个问题,所以这里尝试#2来解释它。

PrimaryUser1拥有www.something.com/PrimaryUser1Site的用户名/密码

他希望为两个人提供子访问权限 - SecondaryUser1和SecondaryUser2到文件夹 - www.something.com/PrimaryUser1Site/SecondaryUser1和www.something.com/PrimaryUser1Site/SecondaryUser2

Mysite.com负责这个子用户管理,因此PrimaryUser1会去那里并向Mysite.com提供他的凭据。 MySite.com在内部使用PrimaryUser1提供的凭据为子用户提供有限的访问权限。现在,SecondaryUser1和SecondaryUser2可以通过MySite.com访问www.something.com/PrimaryUser1Site上各自的文件夹

现在,问题出现了,我应该如何存储PrimaryUser1提供的凭据?

8 个答案:

答案 0 :(得分:4)

第一条规则:永远不要存储密码! 第二条规则:使用额外的盐计算哈希密码,并将其存储在数据库中。 第三条规则:用户名(大写)可以用作盐,但最好添加一点盐作为盐! (一些额外的文字,最好是长的。) 第四条规则:哈希算法的安全性无关紧要,迟早会被黑客攻击。所需要的只是时间! 第五条规则:您网站的安全性取决于其背后的价值。内容越有价值,您受攻击的可能性就越大! 第六条规则:您迟早会发现您的网站被黑客攻击但不是通过黑客密码,而是通过代码中其他地方的漏洞。现在您已经实施了一些强大的安全措施,最大的风险是期望您的网站安全。 第七条规则:所有安全都可以被破解,所有网站都可以被黑客攻击,所有的秘密都可以被发现,只要有人愿意投入足够的时间这样做。

安全是一种幻觉,但只要没有人打破它,你就可以继续梦想!始终为粗暴的觉醒做好准备,这需要你重新重建你的错觉。 (换句话说,定期备份!(最好是每天。)不要覆盖上周的备份,并确保每周至少保留一次备份,以防你发现你的网站在几个月前被黑了,所有从那以后你的备份就被感染了!

现在,如果您确实需要存储密码,请使用用户名加密码的哈希值。然后用哈希加盐再次哈希!更好的是,创建一个salt列表(只是单词列表),每当创建一个新的用户帐户时,选择一个随机盐字用于哈希他的用户名和密码。使用用户帐户存储salt的索引,以便在他再次登录时知道要使用哪个。

和: 八条规则:始终使用HTTPS!它并不像大多数人那样安全,但确实给用户带来了安全感!


由于您已添加了文字,我会添加更多答案。

由于您希望user1授予对用户2的临时访问权限,因此您需要一个辅助用户表。 (或者使用父用户ID扩展用户表。还要添加时间戳以跟踪帐户年龄。用户1可以创建凭据,这是以正常方式完成的。只需存储具有组合用户名和盐的哈希。在这种情况下,使用用户1的用户名作为额外的盐!只需确保在用户1注销或经过一定时间后禁用用户2帐户。并允许用户1再次启用所有帐户他创建了,所以他们可以重复使用帐户,而不必一直创建新帐户。

安全性不是依赖于主要或次要用户的问题。一般来说,以同样的方式对待它们!次要用户有额外的奖励,您可以使用主帐户作为额外的盐。其余部分与身份验证无关。这是您正在处理的授权。虽然身份验证和授权之间存在很强的关系,但请注意,您应将它们视为两种不同的独立技术。

当用户1登录时,他被授予对主站点的访问权限。当他授予对用户2的访问权限时,用户2获得一组减少的角色。但这与存储用户名或密码无关。您只有一个用户ID,恰好是某些角色或组的成员。或者不是,但那些将无法访问。

他们都是用户,一个人拥有比另一个人更多的权利。

答案 1 :(得分:1)

这取决于您的主站点和辅助站点达成一致的身份验证类型。是表单身份验证,HTTP Basic还是HTTP Digest?如果是表单或基本表示您没有选择,则必须存储密码,因此您唯一的选择是对其进行加密。您无法存储密码哈希,因为您必须在身份验证期间为表单和HTTP Basic提供明文。存储加密密码时出现的问题是由于密码学的使用不正确(即,您没有使用IV或盐,或者您没有正确使用流密码),但更重要的是,您将拥有密钥管理问题(在哪里存储用于加密密码的密钥以及如何从非交互式服务/恶魔访问密码)。

如果第三方网站接受HTTP摘要,那么您运气好,可以存储摘要哈希的HA1 hash部分(即username:realm:password的MD5),因为您可以构建摘要从HA1开始直接回应。

我没有说明用户如何配置辅助凭证(即,如何获得辅助站点用户名和密码),我假设您已经获得了受保护的通道(即从客户端到主站点的HTTPS) )。

BTW这假设您的主站点和辅助站点之间进行身份验证,并且辅助站点内容通过对主站点发出的HTTP请求进行隧道传输。如果不是这种情况,并且实际直接从浏览器访问辅助站点,则辅助站点必须支持某些经过身份验证的基于令牌的第三方授权,如OAuth。当浏览器实际需要凭据时,依赖凭据身份验证并在主站点上存储凭据有很多问题甚至都不值得讨论。

答案 2 :(得分:0)

您是否考虑过像Stack Overflow那样接受OpenID?这样你根本不负责存储密码。

答案 3 :(得分:0)

有一个更好的解释方法:(

但如果您只是想知道如何安全地存储密码,请执行以下操作:

用户名:john,密码:传递

key ='!! @ ijs09789 **& *';

MD5(username.password.key);

当他们登录时只检查md5(username.password.key)=是否等于db中的那个 - 你也可以使用sha1和/或任何其他加密方法。

http://us.php.net/md5& http://us.php.net/sha1

答案 4 :(得分:0)

只有一种方法可以做到这一点,对用户来说可能太麻烦了。

您可以使用公钥/私钥加密用户密码,用户保留密钥,以便只有在密钥提交回服务器时才能解密密码。实现这一目标的唯一方法是使用一些自动提交信息的Web浏览器插件。

无论哪种方式,你都可以随时通过数据包嗅探与服务器之间的通信,因此它仍然无意义。

答案 5 :(得分:0)

如果您想自己存储密码,最好的方法是使用单向散列算法,如MD5或SHA-1。这种方法的优点是无法从散列值中获取密码。

您选择哪种算法取决于您使用的精确产品。一些前端工具提供这些功能,一些数据库产品也是如此。否则你需要第三方库。

修改

次要用户应该拥有自己的passowrds。他们为什么不呢?

答案 6 :(得分:0)

永远不要将密码存储在数据库中,而是存储每个密码的 salted and hashed version

如果这是中文,请查看article

答案 7 :(得分:0)

你太复杂了。您需要停止尝试混合身份验证和授权。

您要做的是为每个人建立凭据,如果他们是“主要”或“次要”用户,此时不要担心。然后在管理用户和主要/次要关系的主站点上,您可以执行主要或次要用户的逻辑,并将所有内容存储在表中。每当主要用户更新与他们的关系时,您授予或拒绝您希望每个次要用户拥有的任何权利和子权限。完成后,您最终需要将相应的用户凭据从主站点复制到辅助站点。

然后,当次要用户想要前往您的服务器场中的任何站点时,他们只会自己验证自己 - 他们从不冒充主要用户!当主要用户给他们“次要”状态时,他们只拥有您授予他们的权利。

-

好的,既然您在评论中拍摄了该解决方案,请考虑以下事项:

首先,我怀疑任何事情都会真正安全。如果您监控用户的活动,您可以随时恢复密码。

现在,这完全脱离了袖口,我没有对其进行密码分析,但检查了所谓的secret sharing方案。将“有效”或“真实”主站点主用户密码存储为共享密钥。使用主用户提供的密码的盐渍哈希作为一个秘密。使用第一个辅助用户给出的密码的salted哈希作为另一个秘密,依此类推每个额外的辅助用户。不要存放盐渍哈希!只需存储盐和受保护的共享密钥。

当用户输入密码时,您将检索受保护的共享密钥,使用其密码的salt和哈希值来生成salted哈希,解密受保护的共享密钥,现在您已获得原始主用户密码。< / p>