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

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

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

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

Bounty的其他信息

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

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

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

谢谢大家

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

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

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


当前回答

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

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

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

其他回答

如果您不能拒绝存储可恢复密码的要求,那么您的反对论点如何?

我们可以正确地散列密码并为用户建立一个重置机制,或者我们可以从系统中删除所有个人身份信息。您可以使用电子邮件地址来设置用户偏好,但仅此而已。使用cookie可以自动提取未来访问的偏好,并在一段合理的时间后丢弃数据。

密码策略中经常被忽视的一个选项是是否真的需要密码。如果你的密码策略所做的唯一一件事就是导致客户服务电话,也许你可以摆脱它。

中途教习所怎么样?

使用强加密存储密码,不要启用重置。

与其重置密码,不如允许发送一次性密码(必须在第一次登录时立即更改)。然后让用户更改为他们想要的任何密码(如果他们选择,是之前的密码)。

你可以把它作为一种重置密码的安全机制来“推销”。

想象一下,有人委托建造一座大型建筑——比方说一座酒吧——下面的对话发生了:

建筑师:对于这种规模和容量的建筑,这里、这里和这里都需要安全出口。 客户:不,那太复杂了,维护起来也太贵了,我不想要任何侧门或后门。 建筑师:先生,消防出口不是可有可无的,这是城市消防法规规定的。 客户:我付你钱不是让你争辩的。照我说的做。

建筑师是否会问如何在没有安全出口的情况下合乎道德地建造这栋建筑?

在建筑和工程行业,对话很可能是这样结束的:

建筑师:这栋建筑没有安全出口是建不起来的。你可以去找其他有执照的专业人士,他会告诉你同样的事情。我现在要走了;等你准备好合作了再打给我。

计算机编程可能不是一个有执照的职业,但人们似乎经常想知道为什么我们的职业没有得到与土木或机械工程师同样的尊重——好吧,不用再看了。这些职业,当遇到垃圾(或完全危险的)要求时,会简单地拒绝。他们知道这不是一个借口,“嗯,我尽力了,但他坚持,我必须按他说的做。”他们可能会因此被吊销执照。

我不知道您或您的客户是否是任何上市公司的一部分,但以任何可恢复的形式存储密码都会导致您无法通过几种不同类型的安全审计。问题不在于某些进入数据库的“黑客”要恢复密码有多难。绝大多数安全威胁来自内部。你需要防止的是一些心怀不满的员工拿走所有的密码,然后把它们卖给出价最高的人。使用非对称加密和将私钥存储在单独的数据库中绝对不能防止这种情况;总有人可以访问私人数据库,这是一个严重的安全风险。

没有道德或负责任的方式以可恢复的形式存储密码。时期。

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

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

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

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

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

用另一种方法或角度来解决这个问题怎么样?询问为什么密码必须是明文:如果是为了让用户可以检索密码,那么严格地说,您实际上不需要检索他们设置的密码(他们不记得它是什么),您需要能够为他们提供一个他们可以使用的密码。

想想看:如果用户需要检索密码,那是因为他们忘记了密码。在这种情况下,新密码和旧密码一样有效。但是,目前使用的常用密码重置机制的缺点之一是,在重置操作中生成的密码通常是一堆随机字符,因此用户很难正确地输入它们,除非他们复制-粘贴。对于不太精明的电脑用户来说,这可能是个问题。

解决这个问题的一种方法是提供自动生成的密码,这些密码或多或少是自然语言文本。虽然自然语言字符串可能没有相同长度的随机字符字符串的熵,但没有人说你的自动生成的密码只需要8个(或10个或12个)字符。通过将几个随机单词串在一起来获得一个高熵自动生成的密码短语(在它们之间留出一个空间,以便能够阅读的人仍然可以识别和键入它们)。6个不同长度的随机单词可能比10个随机字符更容易正确输入,而且它们的熵也更高。例如,从大写字母、小写字母、数字和10个标点符号(总共72个有效符号)中随机抽取的10个字符的密码的熵值为61.7比特。使用7776个单词的字典(如Diceware所使用的),可以随机选择6个单词的密码短语,密码短语的熵将为77.4位。更多信息请参见Diceware FAQ。

一个约77比特熵的密码短语:“承认散文耀斑表敏锐的天赋” 一个约有74位熵的密码:“K:&$R^tt~qkD”

我知道我更喜欢输入短语,使用复制-粘贴,短语也不会比密码更容易使用,所以没有损失。当然,如果你的网站(或任何受保护的资产)不需要77位熵来自动生成密码短语,那就生成更少的单词(我相信你的用户会喜欢的)。

我理解有人的观点,有些受密码保护的资产实际上没有很高的价值,所以密码被泄露可能不是世界末日。例如,我可能不会在意我在各种网站上使用的80%的密码被破解:唯一可能发生的事情就是有人用我的名字发垃圾邮件或发帖。那样不太好,但他们又不会侵入我的银行账户。然而,鉴于许多人在他们的论坛网站上使用的密码与他们的银行账户密码(可能还有国家安全数据库密码)相同,我认为最好将这些“低价值”密码作为不可恢复的密码来处理。