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

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

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

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

Bounty的其他信息

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

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

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

谢谢大家

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

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

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


当前回答

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

通过电子邮件发送密码对用户有好处吗?不。他们从一次性密码重置链接中获益更多,这有望让他们选择一个他们能记住的密码。 在屏幕上显示密码对用户有好处吗?不,原因和上面一样;他们应该选择一个新密码。 让技术支持人员告诉用户密码对用户有好处吗?没有;同样,如果支持人员认为用户的密码请求已经过正确验证,那么为用户提供新密码和更改密码的机会对用户更有利。此外,电话支持比自动密码重置更昂贵,所以该公司也没有受益。

从可恢复的密码中获益的似乎只有那些怀有恶意的人,或者那些需要第三方密码交换的糟糕api的支持者(请永远不要使用这些api !)也许你可以通过如实向客户陈述公司存储可恢复密码没有获得任何好处,只会承担责任来赢得争论。

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

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

但如果你出于某种原因(请告诉我们原因)真的,真的,真的需要一个可恢复的密码,你可以通过给他们一个非密码认证系统来保护用户,以免他们的其他在线帐户受到潜在的威胁。因为人们已经熟悉用户名/密码系统,这是一个行之有效的解决方案,这将是最后的手段,但肯定有很多创造性的替代密码的方法:

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

其他回答

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

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

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

入侵网站的数据库,以获得(“pass-a”,用户id)对或对。 从配置文件中获取网站的id 找到并侵入远程密码数据库。

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

总而言之,你让黑客的工作变得更加困难。在任何一台服务器上出现安全漏洞的几率都是一样的,但是有意义的数据(帐户和密码的匹配)将很难组合起来。

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

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

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

抱歉,但只要你有办法破解他们的密码,就不可能是安全的。痛苦地抗争,如果你输了,CYA。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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