我应该如何道德地处理用户密码存储以供以后的明文检索?

当我继续构建越来越多的网站和Web应用程序时,我经常被要求存储用户的密码,如果/当用户有问题时(通过电子邮件发送忘记的密码链接,通过电话等),当我可以时,我强烈反对这种做法,我做了很多“额外”的编程,使密码重置和管理帮助成为可能,而无需存储他们的实际密码。

当我无法对抗它(或无法获胜)时,我总是以某种方式对密码进行编码,以便它至少不会作为明文存储在数据库中-尽管我知道如果我的数据库被黑客入侵,罪魁祸首破解密码不会花费太多时间,所以这让我不舒服。

在一个完美的世界里,人们会经常更新密码,而不是在许多不同的网站上重复密码——不幸的是,我认识很多人都有相同的工作/家庭/电子邮件/银行密码,甚至在他们需要帮助的时候免费给我密码。

在道德和伦理上,我觉得有责任保护可能是什么,对于一些用户来说,他们的生计,即使他们对待它的尊重要少得多。我敢肯定,有很多途径的方法和参数要盐哈希和不同的编码选项,但是否有一个单一的“最佳实践”,当你必须存储它们?在几乎所有的情况下,我使用PHP和MySQL,如果这使我应该处理细节的方式有任何不同。

关于Bounty的更多信息

我想澄清,我知道这不是你想做的事情,在大多数情况下,拒绝这样做是最好的。然而,我不是在寻找一个关于采取这种方法的优点的讲座--我是在寻找如果你确实采取这种方法,可以采取的最佳步骤。

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

在这样的系统中,如果用户没有获得这种级别的访问帮助,这些人口统计数据的流失率可能会阻碍应用程序,因此请记住这样的设置来回答。

感谢大家

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

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

另外,感谢Stack社区中为这个问题投票并/或将其标记为收藏夹的每个人。我认为获得100票是一种恭维,并希望这次讨论帮助了其他和我一样关心这个问题的人。

86172 次浏览

中途之家怎么样?

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

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

您可以将其“出售”为重置密码的安全机制。

使用公钥对密码+盐进行加密。登录时检查存储的值是否等于根据用户输入+盐计算出的值。如果有时间需要恢复密码明文,可以使用私钥手动或者半自动解密。私钥可能存储在其他地方,可能还会对称加密(那时需要人工解密)。

我认为这实际上有点类似于Windows恢复代理的工作方式。

  • 密码是加密存储的
  • 人们无需解密为明文即可登录
  • 密码可以恢复为明文,但只能使用私钥,私钥可以存储在系统之外(如果您愿意,可以存储在银行保险箱中)。

对不起,但只要你有办法破解他们的密码,就不可能安全。与之苦战,如果你输了,CYA。

我认为你应该问自己的真正问题是:我怎样才能更好地说服别人?

不要放弃。你可以用来说服你的客户的武器是不可否认性。如果你可以通过任何机制重建用户密码,你就给了他们客户一个合法的不可否认机制,他们可以拒绝任何依赖于该密码的交易,因为供应商没有办法证明他们没有重建密码并自己通过交易。如果密码正确地存储为摘要而不是密文,这是不可能的,因此要么最终客户自己执行了交易,要么违反了他对密码的注意义务。在这两种情况下,责任都在他身上。我处理过的案例价值数亿美元。不是你想弄错的东西。

将用户安全问题的答案作为加密密钥的一部分,不要将安全问题答案存储为纯文本(而是散列)

Michael Brooks对CWE-257相当直言不讳-无论您使用什么方法,您(管理员)仍然可以恢复密码。那么这些选项怎么样:

  1. 使用别人的公钥-一些外部机构加密密码。这样您就无法亲自重建它,用户将不得不前往该外部机构并要求恢复他们的密码。
  2. 使用从第二个密码短语生成的密钥加密密码。在客户端执行此加密,并且永远不会将其清楚地传输到服务器。然后,要恢复,请通过从他们的输入重新生成密钥再次在客户端进行解密。诚然,这种方法基本上使用第二个密码,但您可以随时告诉他们将其写下来,或使用旧的安全问题方法。

我认为1.是更好的选择,因为它使您能够指定客户公司内部的人来持有私钥。确保他们自己生成密钥,并将其与说明一起存储在保险箱等中。您甚至可以通过选择仅加密并将密码中的某些字符提供给内部第三方来增加安全性,这样他们就必须破解密码才能猜测它。将这些字符提供给用户,他们可能会记住它是什么!

处理丢失/忘记的密码:

没有人应该能够恢复密码。

如果用户忘记了密码,他们至少必须知道他们的用户名或电子邮件地址。根据请求,在用户表中生成一个GUID,并发送一封电子邮件,其中包含一个链接,该链接包含guid作为用户电子邮件地址的参数。

链接后面的页面验证参数guid是否真的存在(可能带有一些超时逻辑),并要求用户提供新密码。

如果您需要热线帮助用户,请在您的赠款模型中添加一些角色,并允许热线角色以已识别用户的身份临时登录。记录所有此类热线登录。例如,Bugzilla向管理员提供此类模拟功能。

想象一下,有人委托建造一座大型建筑-一个酒吧,让我们说-然后发生以下对话:

建筑师:对于这样大小和容量的建筑,你需要在这里、这里和这里有消防出口。
客户:不,这太复杂和昂贵的维护,我不想要任何侧门或后门。
建筑师:先生,消防出口不是可选的,根据城市消防法规,它们是必需的。
客户端:我不是雇你来争论的。照我说的做。

那么建筑师是否会问如何在没有消防出口的情况下合乎道德地建造这座建筑?

在建筑和工程行业,谈话最有可能这样结束:

建筑师:这栋楼不能没有消防通道。你可以去找任何其他有执照的专业人士,他会告诉你同样的事情。我现在就走;当你准备好合作的时候给我打电话。

计算机编程可能不是一个许可的职业,但人们似乎常常想知道,为什么我们的职业没有得到与土木工程师或机械工程师同样的尊重——好吧,别再想了。这些职业在收到垃圾(或完全危险)的要求时,会干脆拒绝。他们知道,这不是一个借口,不能说,“好吧,我尽了最大努力,但他坚持,我必须按他说的做。”他们可能会因为这个借口而失去执照。

我不知道您或您的客户是否属于任何上市公司,但以任何可恢复的形式存储密码会导致您无法通过几种不同类型的安全审核。问题不在于访问您的数据库的“黑客”恢复密码有多困难。绝大多数安全威胁是内部的。您需要防范的是一些不满的员工带走所有密码并将其出售给出价最高的人。使用非对称加密并将私钥存储在单独的数据库中绝对不能防止这种情况;总是会有有人访问私有数据库,这是一个严重的安全风险。

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

根据我对这个问题的评论:
我最初的反应与@Michael Brooks非常相似,直到我意识到,就像@stefan w一样,这里的问题是破碎的需求,但这些就是它们。但是,我突然想到,情况可能并非如此!这里缺少的一点是应用程序资产的未说出的。简单地说,对于一个低价值系统,一个完全安全的身份验证机制,涉及所有过程,将是矫枉过正的,是错误的安全选择。
显然,对于银行来说,“最佳实践”是必须的,并且没有办法在道德上违反CWE-257。但是很容易想到低价值的系统,在那里它是不值得的(但是仍然需要简单的密码)。

重要的是要记住,真正的安全专业知识是找到适当的权衡,而不是教条地散布任何人都可以在线阅读的“最佳实践”。

因此,我建议另一种解决方案:
根据系统的价值,除非系统是适当的低价值,没有“昂贵”的资产(包括身份本身),有有效的业务要求,使适当的流程不可能(或足够困难/昂贵),客户端知道所有的警告…
然后它可能是适当的,简单地允许可逆加密,没有特殊的箍跳过。我只是说根本不用担心加密,因为它非常简单/便宜(即使考虑到可使用的密钥管理),并且它确实提供了一些保护(超过实现它的成本)。此外,值得研究如何为用户提供原始密码,无论是通过电子邮件,显示在屏幕上,等。由于这里的假设是被盗密码的价值(即使在总数中)非常低,因此这些解决方案中的任何一个都可能是有效的。


由于正在进行热烈的讨论,实际上是几次热烈的讨论,在不同的帖子和单独的评论线程中,我将补充一些澄清,并回应这里其他地方提出的一些非常好的观点。

首先,我认为这里的每个人都很清楚,允许检索用户的原始密码是不好的做法,通常不是一个好主意。这一点没有争议…
此外,我将强调,在许多情况下,不,大多数情况-这真的是错误的,甚至肮脏,肮脏,丑陋

然而,问题的关键是围绕的原则有没有可能不需要的情况禁止这样做,如果是这样,如何在最适合形势的正确方式中这样做。

现在,正如@Thomas,@sfusenegger和其他一些人所提到的,回答这个问题的唯一正确方法,是对任何给定(或假设)的情况进行彻底的风险分析,了解利害关系,值得保护的程度,以及还有哪些其他缓解措施可以提供这种保护。
不,这不是一个流行语,这是一个基本的,最重要的工具,为一个真实的现场安全专业人员。最佳实践是好到一定程度(通常作为指导方针,缺乏经验和黑客),之后,深思熟虑的风险分析接管。

你知道,这很有趣-我一直认为自己是安全狂热分子之一,不知何故,我站在那些所谓的“安全专家”的对立面……好吧,事实是-因为我是一个狂热分子,一个真正的现实生活中的安全专家-我不相信在没有所有重要的风险分析的情况下喷出“最佳实践”教条(或CWE)。“当心安全狂热者,他们在不知道他们正在防御的实际问题是什么的情况下,迅速应用工具腰带中的所有东西。更多的安全性并不一定等同于良好的安全性。”风险分析和真正的安全狂热分子,会指出一个更聪明的,基于价值/风险的权衡,基于风险,潜在损失,可能的威胁,互补的缓解措施等任何“安全专家”,不能指出健全的风险分析作为他们的建议的基础,或支持逻辑权衡,而是宁愿喷出教条和CWE,甚至不了解如何执行风险分析,只是安全黑客,他们的专业知识不值得他们打印出来的卫生纸。

事实上,这就是我们如何得到机场安全的荒谬之处。

但在我们讨论在这种情况下做出适当的权衡之前,让我们看看明显的风险(显然,因为我们没有关于这种情况的所有背景信息,我们都在假设-因为问题是假设的情况可能会有什么……)
让我们假设一个低价值的系统,但不是那么琐碎,它是公共访问-系统所有者希望防止随意冒充,然而“高”安全性并不像易用性那么重要。(是的,接受任何精通脚本的孩子都可以攻击网站的风险是一个合法的权衡…等等,APT现在不是很流行吗…?)
举个例子,假设我正在为一个大家庭聚会安排一个简单的网站,让每个人都能集思广益,决定今年我们想去哪里露营。我不太担心一些匿名黑客,甚至弗雷德表哥一再建议回到Wantanamanabikiliki湖,因为我担心Erma阿姨在需要的时候无法登录。现在,Erma阿姨,作为一名核物理学家,不太擅长记住密码,甚至根本不擅长使用电脑……所以我想为她消除所有可能的摩擦。再一次,我不担心黑客,我只是不想错误登录的愚蠢错误-我想知道谁来了,他们想要什么。

无论如何。
那么,如果我们对称加密密码,而不是使用单向哈希,我们的主要风险是什么?

  • 冒充用户?不,我已经接受了这个风险,不有趣。
  • 邪恶的管理员?好吧,也许……但再一次,我不在乎是否有人可以冒充另一个用户,内部或没有……无论如何,一个恶意的管理员会得到你的密码无论什么-如果你的管理员坏了,它的游戏结束了。
  • 另一个被提出的问题是,身份实际上是在几个系统之间共享的。啊!这是一个非常有趣的风险,需要仔细研究。
    让我首先断言共享的不是实际的身份,而是证明或身份验证凭据。好吧,由于共享密码将有效地允许我进入另一个系统(比如,我的银行账户,或gmail),这实际上是相同的身份,所以这只是语义学…除了这不是。在这种情况下,身份由每个系统单独管理(尽管可能有第三方ID系统,例如OAuth——尽管如此,它与系统中的身份分离——稍后会详细介绍)。因此,这里的核心风险点是用户愿意将他的(相同的)密码输入几个不同的系统-现在,我(管理员)或我网站的任何其他黑客都可以访问Erma阿姨的核导弹网站密码。

嗯。

你觉得这里有什么不对劲吗?

它应该。

让我们从保护核导弹系统的事实开始,我只是在为我的家人建造一个该死的家庭郊游网站。那么这是谁的责任呢?嗯…核导弹系统怎么样?废话。
第二,如果我想窃取某人的密码(众所周知,在安全站点和不太安全的站点之间反复使用相同密码的人)-我为什么要打扰你的网站?或者努力解决你的对称加密?Goshdarnitall,我可以设置我自己的简单网站,让用户注册接收关于他们想要的任何东西的非常重要的新闻…… Puffo Presto,我“偷”了他们的密码。

是的,用户教育总是会回来咬我们一口,不是吗?
你对此无能为力……即使你想在你的网站上散列他们的密码,做TSA能想到的一切,你为他们的密码增加了保护一点都没有,如果他们要继续乱七八糟地把密码粘在他们撞到的每个网站上。甚至不要费心去尝试。

换句话说,你没有他们的密码,所以不要试图表现得像你一样。

所以,我亲爱的安全专家,作为一个老太太用来问温迪的,“风险在哪里?

另外几点,回答上面提出的一些问题:

  • CWE既不是法律,也不是规章,甚至也不是标准,它是共同弱点的集合,即“最佳实践”的倒置。
  • 共享身份的问题是一个实际问题,但是被这里的反对者误解(或歪曲)了。这是一个共享身份本身的问题(!),而不是破解低价值系统上的密码。如果你在低价值和高价值系统之间共享密码,问题已经存在了!
  • 顺便说一句,前面的点实际上会指向反对,对这些低价值系统和高价值银行系统都使用OAuth等。
  • 我知道这只是一个例子,但(可悲的是)联邦调查局的系统并不是最安全的,不像你的猫的博客的服务器,但也没有超过一些更安全的银行。
  • 加密密钥的分裂知识或双重控制不仅仅发生在军队中,事实上,PCI-DSS现在基本上来自所有商家,所以它不再真正存在(如果价值证明它是合理的)。
  • 对于所有抱怨这些问题使开发人员职业看起来如此糟糕的人:正是这样的答案使安全职业看起来更糟。再次,以业务为中心的风险分析是必需的,否则你会让自己变得无用。除了错了。
  • 我想这就是为什么只是让一个普通的开发人员承担更多的安全责任,而不训练他以不同的方式思考,并寻找正确的权衡,这不是一个好主意。无意冒犯,对你们这些人来说,我完全赞成-但更多的培训是必要的。

哇,好长的帖子…
但要回答你最初的问题,@Shane:

  • 向客户解释正确的做事方式。
  • 如果他仍然坚持,解释更多,坚持,争论。如果需要,发脾气。
  • 向他解释商业风险。细节很好,数字更好,现场演示通常是最好的。
  • 如果他仍然坚持,并提出有效的商业理由-是时候让你做出判断了:
    这个网站是低到无价值的吗?它真的是一个有效的商业案例吗?它对你来说足够好吗?你可以考虑没有其他风险,这将超过有效的商业原因吗?(当然,客户端不是恶意网站,但这是废话)。如果是这样,那就继续吧。不值得(在这种假设的情况下)付出努力、摩擦和失去用处来实施必要的过程。任何其他决定(同样,在这种情况下)都是一个糟糕的权衡。

所以,底线,和一个实际的答案-用一个简单的对称算法加密它,用强ACL保护加密密钥,最好是DPAPI或类似的东西,记录它并让客户端(足够高级的人做出决定)签署它。

您不能道德地存储密码以供以后明文检索。就这么简单。即使是Jon Skeet也不能道德地存储密码以供以后明文检索。如果您的用户可以以某种方式以纯文本形式检索密码,那么在您的代码中发现安全漏洞的黑客也可能如此。这不仅仅是一个用户的密码被泄露,而是他们所有人。

如果您的客户对此有问题,请告诉他们以可恢复的方式存储密码是违法的。无论如何,在英国,1998年的《数据保护法》(特别是附表1,第二部分,第9段)要求数据控制者使用适当的技术措施来保护个人数据的安全,同时考虑到数据泄露可能造成的伤害等因素——对于在站点之间共享密码的用户来说,这可能是相当大的伤害。如果他们仍然难以理解这是一个问题,请向他们指出一些现实世界的例子,例如这一个

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

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

更新时间:我们现在开始看到针对未能妥善保护用户密码的公司的诉讼和起诉。示例:LinkedIn面临500万美元的集体诉讼索尼因PlayStation数据黑客被罚款25万英镑。如果我没记错的话,LinkedIn实际上正在加密其用户的密码,但它使用的加密太弱而无效。

在注册时通过电子邮件发送明文密码,在加密和丢失之前呢?我见过很多网站这样做,从用户的电子邮件中获取密码比将其留在服务器/公司上更安全。

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

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

另一种可能性是有两个同时允许访问帐户的密码。一个是用户管理的“普通”密码,另一个是只有支持人员知道的骨架/主密钥,对所有用户都是一样的。这样,当用户遇到问题时,支持人员可以使用主密钥登录帐户,并帮助用户将密码更改为任何密码。不用说,系统也应该记录所有使用主密钥的登录。作为一项额外措施,无论何时使用主密钥,您都可以验证支持人员的凭据。

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

万能钥匙不一定像最初看起来那么糟糕。我曾在一家国防工厂工作,那里的员工意识到,在某些场合,大型计算机操作员需要有“特殊权限”。他们只需将特殊密码放入一个密封的信封中,并用胶带贴在操作员的办公桌上。要使用密码(操作员不知道),他必须打开信封。每次换班时,轮班主管的工作之一就是检查信封是否被打开,如果被打开,密码是否立即被更改(由另一个部门更改),新密码被放入一个新信封,整个过程重新开始。操作员将被询问他为什么打开它,事件将被记录在案。

虽然这不是我设计的程序,但它确实有效,并提供了出色的问责制。一切都被记录和审查,加上所有操作员都有国防部的秘密许可,我们从来没有任何滥用行为。

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

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

但话说回来,如果这个可怜的家伙的客户有良好的管理,他们不会要求这样一个安全妥协的解决方案摆在首位,现在他们会吗?

在独立服务器上打开数据库,并为每个需要此功能的Web服务器提供加密的远程连接。
它不一定是关系数据库,它可以是具有FTP访问权限的文件系统,使用文件夹和文件而不是表和行。
如果可以的话,给Web服务器只写权限。

像普通人一样将密码的不可检索加密存储在站点的数据库中(我们称之为“pass-a”):)
在每个新用户(或密码更改)上,在远程DB中存储密码的普通副本。使用服务器的id,用户的ID和“pass-a”作为此密码的复合密钥。您甚至可以在密码上使用双向加密,以便晚上睡得更好。

现在,为了让某人同时获得密码和它的上下文(站点ID+用户ID+“pass-a”),他必须:

  1. 破解网站的数据库以获取(“pass-a”,用户ID)对或对。
  2. 从一些配置文件中获取网站的ID
  3. 找到并侵入远程密码数据库。

您可以控制密码检索服务的可访问性(仅将其公开为安全的Web服务,每天仅允许一定数量的密码检索,手动执行等),甚至为此“特殊安全安排”收取额外费用。密码检索数据库服务器相当隐蔽,因为它不提供许多功能,并且可以更好地保护(您可以严格定制权限,流程和服务)。

任何单个服务器上的安全漏洞的机会仍然是相同的,但有意义的数据(帐户和密码的匹配)将很难组装。

读完这一部分:

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

在这些系统中,磨损率从这些人口统计数据中应用程序如果用户不鉴于这种级别的访问援助,所以请用这样的设置来回答注意!

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

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

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

评论我的建议有什么不好,我会建议一个真正做到你最初想要的解决方案。

在回答这个问题时,已经有很多关于用户安全问题的讨论,但我想补充一点好处。到目前为止,我还没有看到提到一个合法的利益将可恢复密码存储在系统上。考虑一下:

  • 用户是否从通过电子邮件将密码发送给他们中受益?不。他们从一次性密码重置链接中获得更多好处,希望这将允许他们选择他们记住的密码。
  • 用户是否从屏幕上显示密码中受益?不,原因与上述相同;他们应该选择一个新密码。
  • 用户是否从支持人员向用户说出密码中受益?不;同样,如果支持人员认为用户对其密码的请求经过正确身份验证,则为用户提供新密码并有机会更改它更有利于用户。此外,电话支持比自动密码重置成本更高,因此公司也不会受益。

似乎唯一可以从可恢复密码中受益的是那些有恶意的人或需要第三方密码交换的糟糕API的支持者(请永远不要使用所说的API!)。

从这些类型的请求的字里行间,你会发现你的客户可能不理解甚至根本不关心密码是如何管理的。他们真正想要的是一个对他们的用户来说不那么难的认证系统。所以除了告诉他们他们实际上不想要可恢复的密码之外,你应该为他们提供一些方法来减轻身份验证过程的痛苦,特别是如果你不需要像银行这样的高安全级别:

  • 允许用户使用他们的电子邮件地址作为他们的用户名。我见过无数用户忘记他们的用户名的案例,但很少有人忘记他们的电子邮件地址。
  • 提供OpenID并让第三方支付用户遗忘的成本。
  • 放松对密码的限制。我敢肯定,当一些网站因为一些无用的要求而不允许使用您的首选密码时,我们都非常恼火,比如“您不能使用特殊字符”或“您的密码太长”或“您的密码必须以字母开头”。此外,如果易用性比密码强度更重要,您可以通过允许更短的密码或不需要混合字符类来放松甚至不愚蠢的要求。放宽限制,用户将更有可能使用他们不会忘记的密码。
  • 不要过期密码。
  • 允许用户重复使用旧密码。
  • 允许用户选择自己的密码重置问题。

但是,如果您出于某种原因(请告诉我们原因)真的,真的,真的需要能够拥有可恢复的密码,您可以通过为他们提供非基于密码的身份验证系统来保护用户免受可能危及他们的其他在线帐户的影响。因为人们已经熟悉用户名/密码系统并且它们是一个很好的解决方案,所以这将是最后的手段,但肯定有很多创造性的密码替代方案:

  • 让用户选择一个数字引脚,最好不是4位数,最好只有在防止暴力尝试的情况下。
  • 让用户选择一个只有他们知道答案的简短答案的问题,永远不会改变,他们会永远记住,他们不介意其他人发现。
  • 让用户输入用户名,然后绘制一个易于记忆的形状,并带有足够的排列以防止猜测(请参阅G1如何解锁手机的这张漂亮的照片)。
  • 对于一个儿童网站,你可以根据用户名(有点像一个身份标识)自动生成一个模糊的生物,并要求用户给这个生物一个秘密名称。然后,系统会提示他们输入生物的秘密名称来登录。

保护凭证安全不是二元操作:安全/不安全。安全就是风险评估,并且是在一个连续体上衡量的。安全狂热分子讨厌这样想,但丑陋的事实是,没有什么是绝对安全的。具有严格密码要求、DNA样本和视网膜扫描的哈希密码更安全,但以开发和用户体验为代价。明文密码远没有那么安全,但实施起来更便宜(但应该避免)。归根结底,这归结为对违规行为的成本/收益分析。你根据被保护数据的价值及其时间价值实施安全性。

某人的密码泄露出去的成本是多少?在给定系统中假冒的成本是多少?对于FBI的电脑来说,成本可能是巨大的。对于Bob一次性的五页网站来说,成本可以忽略不计。专业人士为客户提供选项,在安全方面,列出任何实施的优势和风险。如果客户要求的东西可能会因为没有遵守行业标准而使他们面临风险,这一点就加倍了。如果客户特别要求双向加密,我保证你会记录你的反对意见,但这不应该阻止你以你知道的最好方式实施。归根结底,这是客户的钱。是的,你应该推动使用单向哈希,但说这绝对是唯一的选择,其他任何事情都是不道德的,这完全是胡说八道。

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

据我所知,没有任何法律(英国的《数据保护法》也没有)明确规定密码必须使用单向哈希存储。这些法律中唯一的要求就是为安全采取0步。如果对数据库的访问受到限制,即使是明文密码也可以在这种限制下合法。

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

在这个问题上采取另一种方法或角度如何?询问为什么密码需要明文:如果这样用户可以检索密码,那么严格来说,你真的不需要检索他们设置的密码(他们无论如何都不记得密码是什么),你需要能够给他们一个密码他们可以使用

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

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

  • 一个大约77位熵的口令:“承认散文耀斑表急性天赋”

  • 一个大约74位熵的密码:“K:&$R^tt~qkD”

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

我理解这样的观点,即有些受密码保护的资产真的没有很高的价值,所以违反密码可能不是世界末日。例如,我可能不在乎我在各种网站上使用的80%的密码是否被泄露:可能发生的只是有人以我的名义发送垃圾邮件或发帖一段时间。那不是很好,但他们不会闯入我的银行账户。然而,考虑到许多人在他们的网站上使用与他们的银行账户(可能还有国家安全数据库)相同的密码,我认为最好将这些“低价值”密码处理为不可恢复。

如果您不能拒绝存储可恢复密码的要求,那么将此作为您的反驳意见如何。

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

密码策略经常忽略的一个选项是是否真的需要密码。如果您的密码策略唯一做的就是引起客户服务电话,也许您可以摆脱它。

我以实现多因素身份验证系统为生,所以对我来说,认为你可以重置或重建密码,同时暂时使用少一个因素来验证用户,仅用于重置/娱乐工作流程是很自然的。特别是使用OTP(一次性密码)作为一些额外因素,如果时间窗口很短,可以降低建议的工作流程的大部分风险。我们已经为智能手机实现了软件OTP生成器(大多数用户已经整天随身携带),并取得了巨大成功。词性:名词在抱怨商业插件出现之前,我要说的是,当密码不是用于验证用户身份的唯一因素时,我们可以降低保持密码易于检索或重置的固有风险。我承认,对于站点之间的密码重用场景,情况仍然不太好,因为用户会坚持使用原始密码,因为他/她也想打开其他站点,但你可以尝试以最安全的方式提供重建的密码(htpps和html上的谨慎外观)。

我也有同样的问题。同样,我总是认为有人入侵了我的系统,这不是“如果”的问题,而是“何时”的问题。

所以,当我必须做一个网站,需要存储可恢复的机密信息,如信用卡或密码,我做的是:

  • 使用:openssl_encrypt(string$data、string$方法、string$密码)加密
  • 数据参数
    • 敏感信息(例如用户密码)
    • 必要时进行序列化,例如,如果信息是多个敏感信息等数据数组
  • 密码参数:使用只有用户知道的信息,例如:
    • 用户车牌
    • 社会安全号码
    • 用户电话号码
    • 用户的母名
    • 在注册时通过电子邮件和/或短信发送的随机字符串
  • 方法arg
    • 选择一种密码方法,如“aes-256-cbc”
  • 从未将“密码”参数中使用的信息存储在数据库中(或系统中的任何位置)

当需要检索这些数据时,只需使用“openssl_decrypt()”函数并向用户询问答案。例如:“要收到您的密码,请回答问题:您的手机号码是多少?”

ps1:永远不要使用存储在数据库中的数据作为密码。如果您需要存储用户的手机号码,那么永远不要使用此信息来对数据进行编码。始终使用只有用户知道或非亲属很难知道的信息。

ps2:对于信用卡信息,如“一键购买”,我所做的是使用登录密码。此密码在数据库(sha1、md5等)中散列,但在登录时,我将纯文本密码存储在会话中或非持久(即内存)安全cookie中。此纯密码永远不会留在数据库中,实际上它总是留在内存中,在部分结束时销毁。当用户单击“一键购买”按钮时,系统使用此密码。如果用户使用Facebook、Twitter等服务登录,那么我会在购买时再次提示密码(好吧,这不是完全的“点击”),或者使用用户用于登录的服务的一些数据(如Facebook ID)。

允许用户检索其原始密码的唯一方法是使用用户自己的公钥对其进行加密。只有该用户才能解密其密码。

因此,步骤将是:

  1. 用户在您的网站上注册(当然是通过SSL),但尚未设置密码。自动登录或提供临时密码。
  2. 您提供存储其公共PGP密钥以供将来检索密码。
  3. 他们上传他们的公共PGP密钥。
  4. 你要求他们设置一个新密码。
  5. 他们提交密码。
  6. 您可以使用可用的最佳密码哈希算法(例如bcrypt)对密码进行哈希。在验证下一次登录时使用它。
  7. 您使用公钥加密密码,并单独存储。

如果用户随后询问他们的密码,您将使用加密(非散列)密码回复。如果用户不希望将来能够检索他们的密码(他们只能将其重置为服务生成的密码),可以跳过步骤3和7。

刚刚看到这个有趣而热烈的讨论。最让我惊讶的是,很少有人注意到以下基本问题:

  • Q1。用户坚持访问纯文本存储密码的实际原因是什么?为什么它有这么大的价值?

用户年龄较大或年轻的信息并不能真正回答这个问题。但是,如果没有正确理解客户的担忧,如何做出商业决策?

为什么重要?因为如果客户要求的真正原因是系统难以使用,那么也许解决确切的原因会解决实际问题?

由于我没有这些信息,也无法与这些客户交谈,我只能猜测:这是关于可用性的,见上文。

我看到的另一个问题是:

  • Q2。如果用户首先不记得密码,为什么旧密码很重要?

这是可能的答案。如果你有一只叫“miaumiau”的猫,用她的名字作为密码,但忘记了,你更愿意被提醒它是什么,还是更愿意被发送类似“#zy*RW(ew”?

另一个可能的原因是用户认为想出一个新密码是一项艰巨的工作!因此,将旧密码发回会让她再次从痛苦的工作中解救出来。

我只是想了解其中的原因,但无论原因是甚么,我们要处理的是原因,而不是原因。

作为用户,我希望事情简单!我不想努力工作!

如果我登录新闻网站看报纸,我想输入1111作为密码并通过!!!

我知道这是不安全的,但我在乎别人访问我的“帐户”吗?是的,他也可以阅读新闻!

该网站是否存储我的“私人”信息?今天读到的新闻?那是网站的问题,不是我的!网站是否向经过身份验证的用户显示私人信息?那就不要在第一时间展示它!

这只是为了表明用户对问题的态度。

总而言之,我不认为这是一个如何“安全地”存储纯文本密码的问题(我们知道这是不可能的),而是如何解决客户的实际问题。

根据我对这个主题的一点了解,我相信如果你正在构建一个带有登录名/密码的网站,那么你甚至不应该在服务器上看到明文密码。密码应该被散列,甚至在离开客户端之前,可能会加盐。

如果您从未看到明文密码,则不会出现检索问题。

此外,我(从网上)收集到(据称)一些算法(如MD5)不再被认为是安全的。我自己无法判断,但这是需要考虑的。

另一个你可能没有考虑过的选择是允许通过电子邮件进行操作。这有点麻烦,但我为一个需要系统“外部”用户查看(只读)系统某些部分的客户端实现了这一点。例如:

  1. 一旦用户注册,他们就拥有完全访问权限(就像普通用户一样网站)。注册必须包含电子邮件。
  2. 如果需要数据或操作而用户不需要记住他们的密码,他们仍然可以执行操作点击一个特殊的“给我发邮件请求许可”按钮,就在常规的“提交”按钮旁边。
  3. 然后将请求发送到带有超链接的电子邮件,询问他们是否希望执行该操作。这类似于密码重置电子邮件链接,但不是重置密码,而是执行一次性动作
  4. 然后用户点击“是”,它确认应该显示数据,或者应该执行操作,显示数据等。

正如你在评论中提到的,如果电子邮件被泄露,这将不起作用,但它确实解决了@joachim关于不想重置密码的评论。最终,他们将不得不使用密码重置,但他们可以在更方便的时间重置,或者根据需要在管理员或朋友的帮助下重置。

这个解决方案的一个转折是将操作请求发送给第三方受信任的管理员。这在老年人、智力障碍、非常年轻或其他困惑的用户的情况下最有效。当然,这需要一个受信任的管理员来支持这些人的行为。

盐和散列用户的密码正常。登录用户时,既允许用户的密码(加盐/散列后),也允许用户按字面输入的内容匹配。

这允许用户输入他们的秘密密码,但也允许他们输入他们的密码的加盐/散列版本,这是有人会从数据库中读取的。

基本上,使盐渍/散列密码也成为“纯文本”密码。