当我继续建立越来越多的网站和网络应用程序时,我经常被要求存储用户的密码,如果/当用户有问题时,它们可以被检索(要么通过电子邮件发送一个忘记密码的链接,通过电话等),当我可以与这种做法作斗争时,我做了大量的“额外”编程,使密码重置和管理协助成为可能,而不存储他们的实际密码。

当我无法对抗它(或无法获胜)时,我总是以某种方式对密码进行编码,这样至少它不会以明文形式存储在数据库中——尽管我知道如果我的数据库被黑客攻击,罪犯不需要花费太多时间就能破解密码,所以这让我感到不舒服。

在一个完美的世界里,人们会经常更新密码,而不会在许多不同的网站上重复密码——不幸的是,我知道很多人都有相同的工作/家庭/电子邮件/银行密码,甚至在他们需要帮助的时候免费给我。如果我的数据库安全程序因为某种原因失败了,我不想成为他们财务崩溃的罪魁祸首。

从道德和伦理上讲,我觉得我有责任保护一些用户的生活,即使他们对他们的生活不那么尊重。 我确信有许多方法和论点可以用于盐散列和不同的编码选项,但当您必须存储它们时,是否存在单一的“最佳实践”?在几乎所有的情况下,我使用PHP和MySQL,如果这使任何不同的方式,我应该处理的细节。

Bounty的其他信息

我想澄清的是,我知道这不是你想要做的事情,在大多数情况下,拒绝这样做是最好的。然而,我并不是在寻求关于采用这种方法的优点的说教,我是在寻找如果你确实采用这种方法,应该采取的最佳步骤。

在下面的注释中,我指出了主要面向老年人、智障人士或非常年轻的人的网站,当他们被要求执行安全密码恢复程序时,他们会感到困惑。尽管在这些情况下,我们可能会发现这很简单,但有些用户需要额外的帮助,要么让服务技术人员帮助他们进入系统,要么通过电子邮件/直接显示给他们。

在这样的系统中,如果用户没有得到这种级别的访问帮助,来自这些人口统计数据的流失率可能会阻碍应用程序,所以请在回答时考虑到这样的设置。

谢谢大家

这是一个有趣的问题,有很多争论,我很喜欢。最后,我选择了一个答案,它既保留了密码安全性(我不必保留纯文本或可恢复的密码),又使我指定的用户群能够登录到一个系统,而不存在我在正常密码恢复中发现的主要缺陷。

像往常一样,由于不同的原因,大约有5个答案我想标记为正确,但我必须选择最好的一个——其余的都是+1。谢谢大家!

同时,感谢Stack社区中为这个问题投票和/或将其标记为最喜欢的人。我把获得100票作为一种赞美,希望这个讨论能帮助到和我有同样担忧的人。


当前回答

像往常一样对用户密码进行盐加散列处理。当用户登录时,允许用户的密码(经过salting/hashing),但也允许用户按字面输入匹配。

这允许用户输入他们的秘密密码,但也允许他们输入他们的咸/散列版本的密码,这是某人将从数据库读取的密码。

基本上,让加盐/散列的密码也是一个“明文”密码。

其他回答

保护凭证不是一个二进制操作:安全/不安全。安全是关于风险评估的,是在连续统上衡量的。安全狂热分子讨厌这样想,但丑陋的事实是,没有什么是完全安全的。具有严格的密码要求、DNA样本和视网膜扫描的散列密码更安全,但以开发和用户体验为代价。明文密码的安全性要低得多,但实现起来成本更低(但应该避免使用)。在一天结束的时候,它归结为一个漏洞的成本/收益分析。您可以根据所保护的数据的值及其时间值来实现安全性。

一个人的密码泄露到野外的代价是什么?给定系统中模拟的成本是多少?对于联邦调查局的电脑来说,代价可能是巨大的。对于Bob的一次性5页网站来说,成本可以忽略不计。专业人员为客户提供选项,并在涉及到安全性时列出任何实现的优势和风险。如果客户要求的某些东西可能会使他们处于风险之中,因为他们未能遵守行业标准,那么情况就会加倍。如果客户明确要求双向加密,我将确保您记录您的反对意见,但这不应该阻止您以您所知道的最佳方式实现。说到底,这是客户的钱。是的,你应该推动使用单向哈希,但说这绝对是唯一的选择,其他任何东西都是不道德的,这完全是无稽之谈。

如果您使用双向加密存储密码,安全性就归结于密钥管理。Windows提供了一些机制来限制对管理帐户和密码的证书、私钥的访问。如果你在其他平台上托管,你需要看看你在那些平台上有什么可用的选项。正如其他人建议的那样,您可以使用非对称加密。

据我所知,没有法律(包括英国的数据保护法案)明确规定密码必须使用单向哈希存储。这些法律中唯一的要求就是采取合理的措施保证安全。如果对数据库的访问受到限制,那么在这种限制下,即使是明文密码也可以合法地使用。

然而,这确实揭示了另一个方面:法律优先权。如果法律优先级建议您必须根据构建系统的行业使用单向散列,那么情况就完全不同了。这是你用来说服你的客户的弹药。除此之外,最好的建议是提供合理的风险评估,记录您的反对意见,并以您可以满足客户要求的最安全的方式实施系统。

看完这部分后:

在下面的注释中,我指出了这一点 网站主要面向 老年人,智障人士,或者非常 年轻会让人困惑 当他们被要求表演 安全密码恢复程序。 虽然我们觉得这很简单 在这些情况下,一些用户需要的是平淡无奇 任何一个的额外帮助 服务技术人员帮助他们进入 系统或通过电子邮件发送/显示 直接给他们。 在这样的系统中,流失率 从这些人口统计数据来看,可能会步履蹒跚 如果用户不是 考虑到这种程度的准入援助, 所以请回答这样的设置 脑海中。

我想知道这些要求中是否有要求可检索的密码系统。例如: 梅布尔阿姨打电话来说:“你的网络程序坏了,我不知道我的密码。”“好的,”客服无人机说,“让我检查一些细节,然后我会给你一个新密码。当你下次登录时,它会询问你是想保留这个密码,还是把它改成更容易记住的密码。”

然后系统设置为知道密码重置发生时,并显示“您想保留新密码还是选择一个新密码”的消息。

对于不太懂电脑的人来说,这比被告知旧密码更糟糕吗?虽然客户服务人员可能会搞恶作剧,但数据库本身在被破坏时要安全得多。

在我的建议中评论不好的地方,我会提出一个解决方案,实际上是你最初想要的。

出于道德考虑,您不能为以后的明文检索存储密码。就这么简单。就连乔恩·斯基特(Jon Skeet)也不能在道德上存储密码以供以后的明文检索。如果您的用户可以以某种方式以纯文本检索密码,那么黑客也可能会在您的代码中发现安全漏洞。这不仅仅是一个用户的密码被泄露,而是所有用户的密码都被泄露了。

如果你的客户对此有意见,告诉他们可恢复的存储密码是违法的。无论如何,在英国,《1998年数据保护法》(特别是附表1,第II部分,第9段)要求数据控制者使用适当的技术措施来保证个人数据的安全,除其他外,考虑到如果数据被泄露可能造成的损害——这对于在不同网站之间共享密码的用户来说可能是相当大的。如果他们仍然无法理解这是一个问题,给他们举一些现实世界的例子,比如下面这个。

允许用户恢复登录的最简单方法是通过电子邮件向他们发送一个一次性链接,该链接可以自动登录,并直接将他们带到一个可以选择新密码的页面。创建一个原型,并展示给他们看。

以下是我写的几篇关于这个主题的博客文章:

http://jamesmckay.net/2009/09/if-you-are-saving-passwords-in-clear-text-you-are-probably-breaking-the-law/ http://jamesmckay.net/2008/06/easy-login-recovery-without-compromising-security/

更新:我们现在开始看到针对未能正确保护用户密码的公司的诉讼和起诉。例子:领英(LinkedIn)遭到500万美元的集体诉讼;索尼因PlayStation数据泄露被罚款25万英镑。如果我没记错的话,LinkedIn实际上对用户的密码进行了加密,但它使用的加密技术太弱了,不太有效。

不要放弃。你可以用来说服你的客户的武器是不可否认性。如果你可以通过任何机制重建用户密码,你就给了他们的客户一个合法的不可抵赖机制,他们可以拒绝任何依赖于该密码的交易,因为供应商无法证明他们没有重建密码并自己完成交易。如果密码被正确地存储为摘要而不是密文,这是不可能的,因此最终客户要么自己执行交易,要么违反了他对密码的注意义务。无论哪种情况,责任完全落在他身上。我处理过的案件中,金额高达数亿美元。不是你想出错的事。

用户是否真的需要恢复(例如被告知)他们忘记的密码是什么,或者他们只是需要能够进入系统?如果他们真正想要的是登录密码,为什么不设置一个程序,简单地将旧密码(不管是什么)更改为支持人员可以提供给丢失密码的人的新密码?

我曾经使用过这样的系统。支持人员无法知道当前密码是什么,但可以将其重置为新值。当然,所有这些重置都应该记录在某个地方,最好的做法是生成一封电子邮件给用户,告诉他密码已被重置。

另一种可能是使用两个同时的密码来访问一个帐户。一个是用户管理的“正常”密码,另一个就像一个骨架/主密钥,只有支持人员知道,对所有用户都是一样的。这样,当用户有问题时,技术支持人员可以用万能钥匙登录到帐户,并帮助用户更改密码。不用说,所有使用主密钥的登录都应该由系统记录。作为一种额外的措施,无论何时使用主密钥,您都可以验证支持人员凭据。

- edit -回应关于没有主密钥的评论:我同意这是不好的,就像我认为允许用户以外的任何人访问用户的帐户是不好的一样。如果你看一下这个问题,整个前提是客户要求一个高度妥协的安全环境。

万能钥匙不需要像乍看之下那么糟糕。我曾在一家国防工厂工作,他们认为主机操作员在某些场合需要有“特殊访问权限”。他们只是把特殊的密码放在一个密封的信封里,并把它贴在操作员的桌子上。要使用密码(接线员不知道),他必须打开信封。每次换班时,值班员的一项工作就是查看信封是否被打开,如果打开了,立即(由其他部门)更改密码,新密码放入新信封,然后重新开始这个过程。操作员将被问及他为什么打开它,这一事件将被记录在案。

虽然这不是我设计的程序,但它确实有效,并提供了良好的问责制。每件事都被记录和审查过,加上所有的操作员都有国防部的秘密许可我们从未有过任何滥用。

由于审查和监督,所有操作员都知道,如果他们滥用打开信封的特权,他们将立即被解雇,并可能受到刑事起诉。

所以我想真正的答案是,如果一个人想把事情做好,就雇佣他们可以信任的人,进行背景调查,并行使适当的管理监督和问责制。

但话说回来,如果这个可怜的家伙的客户有良好的管理,他们就不会在第一时间要求这样一个安全折衷的解决方案,不是吗?