How should I ethically approach user password storage for later plaintext retrieval?
当我继续构建越来越多的网站和Web应用程序时,我经常被要求以一种方式存储用户的密码,如果/当用户有问题时(通过电子邮件发送忘记的密码链接,通过电话等),可以检索到这些密码。当我可以痛击这种做法时,我会做很多"额外的"程序。使密码重置和管理协助在不存储实际密码的情况下成为可能。
当我无法与之抗争(或无法获胜)时,我总是以某种方式对密码进行编码,以使其至少不会以明文形式存储在数据库中,尽管我知道如果我的数据库被黑客攻击,罪犯破解密码不会花费太多时间,因此让我感到不舒服。
在一个完美的世界里,人们会经常更新密码,而不是在许多不同的网站上重复密码。不幸的是,我认识许多人,他们有相同的工作/家庭/电子邮件/银行密码,甚至在他们需要帮助时免费提供给我。如果我的数据库安全程序因某种原因失败,我不想成为他们财务崩溃的罪魁祸首。
从道德和伦理上讲,我觉得有责任保护一些用户的生活,即使他们对生活不那么尊重。我敢肯定,有许多方法和参数可以用来改变哈希和不同的编码选项,但是当你必须存储它们时,有没有一个"最佳实践"呢?在几乎所有的情况下,我都在使用PHP和MySQL,如果这对我处理细节的方式有任何影响的话。
奖励附加信息
我想澄清一下,我知道这不是你想做的事情,在大多数情况下,拒绝这样做是最好的。不过,我并不是在找一个关于采用这种方法优点的讲座。如果你确实采用这种方法,我正在寻找最好的步骤。
在下面的一个注释中,我指出,当人们被要求执行安全密码恢复程序时,主要面向老年人、精神障碍者或非常年轻的人的网站可能会变得令人困惑。尽管在这种情况下,我们可能会发现它很简单,也很平常,但有些用户需要额外的帮助,要么让服务技术帮助他们进入系统,要么让它直接通过电子邮件/显示给他们。
在这样的系统中,如果用户没有得到这一级别的访问帮助,那么这些人口统计数据的消耗率可能会使应用程序陷入困境,因此请记住这样的设置。
谢谢大家
这是一个有趣的问题,有很多争论,我很喜欢。最后,我选择了一个既保留密码安全性(我不必保留纯文本密码或可恢复密码),又使我指定的用户群能够登录到系统中,而不会出现我从正常密码恢复中发现的主要缺陷。
和往常一样,有大约5个答案,我想根据不同的原因将其标记为正确答案,但我必须选择最好的答案——其余的答案都是A+1。谢谢大家!
另外,感谢Stack社区中投票支持这个问题和/或将其标记为最喜爱的人。我把获得100票作为一种赞美,希望这次讨论能帮助其他和我一样关心的人。
在这个问题上采取另一种方法或角度如何?询问为什么密码必须是纯文本的:如果这样用户就可以检索密码,那么严格地说,您实际上不需要检索他们设置的密码(他们不记得密码是什么),您需要能够给他们一个他们可以使用的密码。
想想看:如果用户需要检索密码,那是因为他们忘记了密码。在这种情况下,新密码和旧密码一样好。但是,目前常用的密码重置机制的一个缺点是,在重置操作中生成的密码通常是一组随机字符,因此用户很难简单地输入正确的密码,除非它们是复制粘贴的。对于不太聪明的计算机用户来说,这可能是个问题。
解决这个问题的一种方法是提供或多或少是自然语言文本的自动生成的密码。虽然自然语言字符串可能没有相同长度的随机字符字符串所具有的熵,但没有什么可以说明自动生成的密码只需要8(或10或12)个字符。通过将几个随机单词串在一起(在它们之间留一个空格,这样任何能阅读的人都能识别和打字),获得一个高熵的自动生成的密码短语。六个长度不同的随机词可能比10个随机字符更容易正确地输入,并且具有更高的熵。例如,从大写、小写、数字和10个标点符号(总共72个有效符号)中随机抽取的10个字符密码的熵将具有61.7位的熵。使用一个包含7776个单词(如骰子软件所使用的)的字典,可以为一个6个单词的密码随机选择,密码将具有77.4位的熵。有关更多信息,请参阅骰子软件常见问题解答。
一个包含大约77位熵的密码短语:"承认散文闪光表锐利的才华"
密码的熵大约为74位:"k:&;$r^tt~qkd"
我知道我更喜欢输入这个短语,使用copy-n-paste,这个短语同样也不容易使用密码,所以不会丢失密码。当然,如果您的网站(或任何受保护的资产)不需要77位熵的自动生成的密码短语,生成更少的单词(我相信您的用户会感激)。
我理解这样的论点:有些受密码保护的资产实际上没有高价值,因此违反密码可能不是世界末日。例如,我可能不在乎我在不同网站上使用的80%的密码是否被破坏:所有可能发生的事情都是有人以我的名义垃圾邮件或张贴了一段时间。那不太好,但他们不会闯入我的银行账户。然而,鉴于许多人在他们的网站上使用的密码和他们在银行账户上使用的密码相同(可能还有国家安全数据库),我认为即使是那些"低值"的密码也是不可恢复的。
假设有人委托建造一座大型建筑——比如说,一个酒吧——然后进行以下对话:
建筑师:对于这种规模和容量的建筑,这里、这里和这里都需要消防通道。客户:不,维修起来太复杂,太贵了,我不想要任何侧门或后门。建筑师:先生,消防出口不是可选的,它们是根据城市的消防规范设置的。客户:我不是付钱让你争论。照我说的去做。
那么建筑师会问如何在没有消防出口的情况下建造这座建筑吗?
在建筑和工程行业,对话最有可能是这样结束的:
建筑师:这座建筑不能没有消防出口。你可以去任何其他持照专业人士那里,他也会告诉你同样的事情。我要走了,你准备好合作的时候给我回电话。
计算机程序设计可能不是一个有执照的职业,但人们常常想知道为什么我们的职业不能得到与土木或机械工程师同样的尊重——好吧,别再看了。这些职业,在处理垃圾(或完全危险的)要求时,只会拒绝。他们知道这不是一个借口说,"好吧,我尽力了,但他坚持,我必须照他说的去做。"他们可能会因此而失去执照。
我不知道您或您的客户是否是任何上市公司的一部分,但以任何可恢复的形式存储密码会导致您未能通过几种不同类型的安全审计。问题不在于某些"黑客"访问您的数据库恢复密码有多困难。绝大多数安全威胁都是内部的。你需要保护的是一些不满的员工带着所有的密码走了,然后卖给出价最高的人。使用非对称加密并将私有密钥存储在单独的数据库中对防止这种情况没有任何作用;总是会有人访问私有数据库,这是一个严重的安全风险。
没有道德或负责任的方式来以可恢复的形式存储密码。时期。
您可以用公钥加密密码+salt。对于登录,只需检查存储值是否等于从用户输入+salt计算得出的值。如果有时间,当密码需要以明文形式还原时,您可以使用私钥手动或半自动解密。私钥可以存储在其他地方,还可以对称加密(需要人工交互才能解密密码)。
我认为这实际上类似于Windows恢复代理的工作方式。
- 密码以加密方式存储
- 人们无需解密就可以登录明文
- 密码可以恢复为纯文本,但只能使用私钥,该密钥可以存储在系统外部(如果需要,可以存储在银行保险箱中)。
不要放弃。你可以用来说服客户的武器是不可否认的。如果您可以通过任何机制重建用户密码,那么您已经为他们的客户提供了一个合法的不可抵赖机制,并且他们可以抵赖依赖该密码的任何交易,因为供应商无法证明他们没有重建密码并将交易置于自己的位置。如果密码被正确地存储为摘要而不是密文,这是不可能的,因此终端客户要么自己执行事务,要么违背了他对密码的注意义务。在这两种情况下,责任完全由他承担。我曾处理过数亿美元的案件。你不想出错。
您不能在道德上存储密码以供以后的纯文本检索。就这么简单。即使是乔恩·斯基特也不能在伦理上为以后的纯文本检索存储密码。如果你的用户可以以明文或其他方式检索密码,那么黑客也有可能在你的代码中发现安全漏洞。这不仅仅是一个用户的密码被泄露,而是所有的密码。
如果您的客户对此有问题,告诉他们可恢复地存储密码是违法的。无论如何,在英国,《1998年数据保护法》(特别是附表1第二部分第9段)要求数据管理员采取适当的技术措施,确保个人数据的安全,同时考虑到如果数据受到损害可能造成的危害,这对那些在站点之间共享密码。如果他们仍然无法摸清这是一个问题的事实,就向他们指出一些现实世界的例子,比如这个例子。
允许用户恢复登录的最简单方法是通过电子邮件向他们发送一个一次性链接,该链接会自动将他们登录,并将他们直接带到一个页面,在那里他们可以选择新密码。创建一个原型并向他们展示它的实际效果。
以下是我写的一些关于这个主题的博客文章:
- http://jamesmckay.net/2009/09/if-you-are-saving-passwords-in-clear-text-you-are-probable-breaking-the-law/
- http://jamesmckay.net/2008/06/easy-login-recovery-without-comprising-security/
更新:我们现在开始看到针对未能正确保护用户密码的公司的诉讼和起诉。例如:LinkedIn遭受了500万美元的集体诉讼;索尼因PlayStation数据黑客行为被罚款25万英镑。如果我没记错的话,LinkedIn实际上是在加密其用户的密码,但是它使用的加密太弱,无法有效地进行加密。
阅读本部分后:
In a note below I made the point that
websites geared largely toward the
elderly, mentally challenged, or very
young can become confusing for people
when they are asked to perform a
secure password recovery routine.
Though we may find it simple and
mundane in those cases some users need
the extra assistance of either having
a service tech help them into the
system or having it emailed/displayed
directly to them.In such systems the attrition rate
from these demographics could hobble
the application if users were not
given this level of access assistance,
so please answer with such a setup in
mind.
我想知道这些要求中是否有任何一项要求要求使用可检索的密码系统。例如:马贝尔姨妈打电话来说:"你的网络程序坏了,我不知道我的密码。""好的,"客服无人机说,"让我检查一些细节,然后我给你一个新密码。下次登录时,它会询问您是否要保留该密码或将其更改为更容易记住的密码。"
然后,系统设置为知道何时发生了密码重置,并显示"您想保留新密码还是选择新密码"消息。
对于那些不懂电脑的人来说,这比被告知他们的旧密码更糟糕吗?而且,尽管客户服务人员可能会受到损害,但数据库本身在被破坏的情况下更安全。
评论一下我的建议有什么坏处,我会提出一个解决方案,它实际上能达到你最初想要的效果。
MichaelBrooks对CWE-257相当直言不讳——事实上,无论您使用什么方法,您(管理员)仍然可以恢复密码。那么这些选项呢:
我想1。是更好的选择,因为它允许您指定客户公司中的某个人持有私钥。确保他们自己生成密钥,并在保险箱中存储指令等。您甚至可以选择只加密密码中的某些字符并将其提供给内部第三方,这样他们就不得不破解密码来猜测它。向用户提供这些字符,他们可能会记住它是什么!
在回答这个问题时,有很多关于用户安全问题的讨论,但是我想补充一点好处。到目前为止,我还没有看到一个合法的好处提到有一个可恢复的密码存储在系统上。考虑一下:
- 将密码通过电子邮件发送给用户是否有好处?不。他们从一次性使用密码重置链接中获得更多的好处,希望这能让他们选择一个能记住的密码。
- 用户的密码显示在屏幕上是否有好处?不,原因与上面相同;他们应该选择一个新密码。
- 让支持人员向用户说出密码对用户有好处吗?不;同样,如果支持人员认为用户对其密码的请求经过了适当的验证,那么给用户一个新密码和更改密码的机会对用户更有利。另外,电话支持比自动密码重置成本更高,因此该公司也没有受益。
似乎唯一能从可恢复的密码中获益的是那些恶意意图的或支持较差的API的人,这些API需要第三方密码交换(请不要使用上述API!).也许你可以通过如实地向你的客户声明公司没有任何好处,只有通过存储可恢复的密码才能获得责任,从而赢得你的论点。
通过阅读这些类型的请求行,您会发现您的客户机可能根本不理解甚至根本不关心如何管理密码。他们真正想要的是一个对他们的用户来说并不那么困难的认证系统。因此,除了告诉他们实际上不需要可恢复的密码之外,您还应该为他们提供使认证过程不那么痛苦的方法,特别是如果您不需要银行这样的高安全级别:
- 允许用户使用其电子邮件地址作为用户名。我见过无数的案例,用户忘记了他们的用户名,但很少有人忘记了他们的电子邮件地址。
- 提供OpenID,让第三方支付用户遗忘的费用。
- 放宽密码限制。我敢肯定,当一些网站因为"你不能使用特殊字符"或"你的密码太长"或"你的密码必须以字母开头"等无用的要求而不允许使用你的首选密码时,我们都非常恼火。此外,如果易用性比密码强度更重要,你甚至可以松开非愚蠢的密码。d通过允许较短的密码或不需要混合字符类的要求。放宽限制后,用户更可能使用他们不会忘记的密码。
- 不要使密码过期。
- 允许用户重新使用旧密码。
- 允许用户选择自己的密码重置问题。
但是,如果您出于某种原因(请告诉我们原因)真的,真的,真的,真的需要有一个可恢复的密码,您可以通过给用户提供一个非基于密码的认证系统来保护用户不受潜在的损害。因为人们已经熟悉用户名/密码系统,并且他们是一个经过良好实践的解决方案,这将是最后的选择,但肯定有很多创造性的密码替代方案:
- 让用户选择一个数字PIN,最好不是4位,最好是在蛮力尝试受到保护的情况下。
- 让用户选择一个答案简短的问题,只有他们知道答案,永远不会改变,他们将永远记住,他们不介意别人发现。
- 让用户输入一个用户名,然后用足够的排列来绘制一个易于记忆的形状,以防止猜测(请参阅这张漂亮的照片,了解g1如何解锁手机)。
- 对于儿童网站,您可以根据用户名(类似于Identicon)自动生成一个模糊的生物,并要求用户为该生物提供一个秘密名称。然后会提示他们输入该生物的秘密名称以登录。
根据我对这个问题的评论:一个重要的观点被几乎所有人都掩盖了…我最初的反应非常类似于@michael brooks,直到我意识到,像@stefanw,这里的问题是打破了需求,但这些就是它们的本质。但后来,我突然想到,情况可能不是这样!这里缺少的一点是应用程序资产的潜在价值。简单地说,对于一个低值系统,一个完全安全的身份验证机制,包括所有涉及的过程,将被过度杀戮,并且是错误的安全选择。显然,对于一家银行来说,"最佳实践"是必须的,并且没有办法违反CWE-257。但是很容易想到低值系统,它不值得(但仍然需要一个简单的密码)。好的。
重要的是要记住,真正的安全专业知识是在寻找适当的权衡,而不是在教条主义地宣扬任何人都可以在线阅读的"最佳实践"。好的。
因此,我建议另一种解决方案:取决于系统的价值,并且只有当系统适当地低价值,没有"昂贵"的资产(身份本身,包括在内),并且有有效的业务需求,使适当的过程不可能(或足够困难/昂贵),并且客户知道所有的警告…然后它可以简单地允许可逆加密,没有特殊的箍跳过去。我只是简短地说了一句,不要再费心加密了,因为它的实现非常简单/便宜(即使考虑到密钥管理的可行性),而且它确实提供了一些保护(比实现它的成本还要高)。另外,值得一看的是如何向用户提供原始密码,无论是通过电子邮件还是在屏幕上显示等。因为这里的假设是被盗密码的价值(甚至是总的来说)非常低,所以这些解决方案中的任何一个都是有效的。好的。
由于有一个活跃的讨论正在进行,实际上是几个活跃的讨论,在不同的帖子和单独的评论线程中,我将添加一些澄清,并对这里其他地方提出的一些非常好的观点作出回应。好的。
首先,我认为这里的每个人都清楚允许检索用户的原始密码是不好的做法,而且通常不是一个好主意。这完全没有争议…此外,我要强调的是,在许多情况下,甚至大多数情况下,这都是错误的,甚至是肮脏、肮脏和丑陋的。好的。
然而,问题的关键在于原则,是否存在不需要禁止的情况,如果是,如何以最适合情况的正确方式禁止。好的。
现在,正如@thomas、@sfusseneger和其他少数人提到的,回答这个问题的唯一正确方法是对任何给定(或假设)的情况进行彻底的风险分析,了解有什么危险,有多少值得保护,以及有哪些其他缓解措施可以提供这种保护。不,这不是一个流行词,这是一个真正的现场安全专业人员最基本、最重要的工具之一。最佳实践在一定程度上是好的(通常作为缺乏经验和黑客的指导方针),在这一点上,深思熟虑的风险分析接管。好的。
你知道,这很有趣-我一直认为自己是一个安全狂热分子,不知怎么的,我是那些所谓的"安全专家"的反面……好吧,事实是——因为我是一个狂热分子,而且是一个现实生活中的安全专家——我不相信在没有所有重要的风险分析的情况下发表"最佳实践"教条(或CWE)。"当心那些安全狂热者,他们很快就把所有的东西都用在了他们的工具带上,却不知道他们正在防御的实际问题是什么。更多的安全并不一定等同于良好的安全。"风险分析,以及真正的安全狂热者,将基于风险、潜在损失、可能的威胁、互补的缓解措施等,指出一个更智能、基于价值/风险的权衡。任何"安全专家"都不能指出可靠的风险分析作为其建议的基础,或支持逻辑权衡,而是宁愿宣扬教条。A和CWE甚至不知道如何进行风险分析,他们只是安全黑客,他们的专业知识不值得他们打印的卫生纸。好的。
事实上,这就是我们如何得到荒谬的机场安全。好的。
但是,在我们讨论在这种情况下要做出的适当权衡之前,让我们先看看明显的风险(很明显,因为我们没有关于这种情况的所有背景信息,所以我们都是假设的——因为问题是可能存在什么假设情况…)让我们假设一个低价值的系统,但不是那么繁琐,它是公共访问-系统所有者希望防止随意的模仿,但"高"安全性并不是最重要的易用性。(是的,这是一个合法的权衡,接受风险,任何熟练的脚本基迪可以黑客网站…等等,现在不流行吗…?)举个例子,假设我正在为一个大型的家庭聚会安排一个简单的地点,让每个人都能集思广益地讨论今年我们想去哪里露营。我不太担心某个匿名黑客,甚至是表兄弗雷德反复提出要回万塔曼纳比基利基湖的建议,因为我担心埃玛姨妈不能在她需要的时候登录。现在,作为一个核物理学家,埃尔玛姨妈不太擅长记住密码,甚至不擅长使用电脑……所以我想消除她所有可能的摩擦。再说一次,我不担心黑客,我只是不想愚蠢的错误登录-我想知道谁来,他们想要什么。好的。
不管怎样。那么,如果我们对称地加密密码,而不是使用单向散列,那么我们在这里的主要风险是什么?好的。
- 模拟用户?不,我已经接受了那个风险,不有趣。
- 邪恶的管理者?嗯,也许…不过,我也不在乎有人能否冒充另一个用户,无论是内部用户还是非内部用户…不管怎样,一个恶意的管理员会得到你的密码,不管怎样-如果你的管理员变坏了,游戏就结束了。
- 另一个被提出的问题是,身份实际上是在几个系统之间共享的。啊!这是一个非常有趣的风险,需要仔细观察。让我先声明共享的不是实际身份,而是证据或身份验证凭证。好吧,因为共享密码将有效地允许我进入另一个系统(例如,我的银行帐户或Gmail),这实际上是相同的身份,所以它只是语义……但事实并非如此。在这种情况下,每个系统都单独管理身份(尽管可能有第三方ID系统,如OAuth,但它与系统中的身份是分开的,稍后将详细介绍)。因此,这里的核心风险点是,用户愿意将自己的(相同的)密码输入几个不同的系统——现在,我(管理员)或我的网站的任何其他黑客都可以访问Erma阿姨的核导弹网站密码。
六羟甲基三聚氰胺六甲醚。好的。
你觉得这里有什么不对劲的地方吗?好的。
它应该。好的。
让我们从保护核导弹系统不是我的责任开始,我只是在为我的家人建造一个Frakkin家庭郊游场地。那是谁的责任呢?嗯…核导弹系统怎么样?杜赫。第二,如果我想窃取某人的密码(已知某人在安全站点之间重复使用相同的密码,而不是如此安全的密码),我为什么要麻烦窃取您的站点?或者是你的对称加密?goshdarnitall,我可以建立自己的简单网站,让用户注册接收关于他们想要的任何东西的非常重要的新闻…Puffo Presto,我"偷"了他们的密码。好的。
是的,用户教育总是回来咬我们,不是吗?你对此无能为力…即使你要在你的网站上散列他们的密码,并且做TSA能想到的所有其他事情,你也给他们的密码增加了保护,而不是一个惠特,如果他们要不断地乱把他们的密码插入他们碰到的每个网站。别费心去尝试。好的。
换句话说,你不拥有他们的密码,所以别再像你那样做了。好的。
所以,我亲爱的安全专家,就像一位老太太问温迪的"风险在哪里?"好的。
另外几点,作为对上述问题的回答:好的。
- CWE不是法律、法规,甚至不是标准。它是一组常见的弱点,即"最佳实践"的反面。
- 共享身份的问题是一个实际的问题,但这里的反对者误解(或歪曲)了这一点。这是一个分享自身身份的问题!!)不是关于破解低值系统上的密码。如果在低值和高值系统之间共享密码,问题就已经存在了!
- 到目前为止,前面的观点实际上是反对对这些低价值系统和高价值银行系统使用OAuth等。
- 我知道这只是一个例子,但(遗憾的是)联邦调查局的系统并不是最安全的。不太像你的猫的博客服务器,但他们也没有超过一些更安全的银行。
- 对加密密钥的分离知识或双重控制不仅仅发生在军事上,事实上PCI-DSS现在基本上需要所有商家都这样做,因此它不再真正存在(如果价值合理的话)。
- 对于所有抱怨这样的问题的人来说,这是使开发人员职业看起来如此糟糕的原因:正是这样的答案,使得安全职业看起来更加糟糕。同样,以业务为中心的风险分析是必需的,否则你会使自己无用。除了犯错。
- 我想这就是为什么不经过不同思考和寻找正确权衡的培训就选择一个普通的开发人员,而把更多的安全责任交给他,这不是一个好主意。没有冒犯的意思,对你们这些人来说,我完全赞成这一点——但更多的训练是有必要的。
唷!好长的帖子…但要回答你最初的问题,@shane:好的。
- 向客户解释正确的做事方法。
- 如果他仍然坚持,再解释,坚持,争论。必要时发脾气。
- 向他解释商业风险。细节很好,数字更好,现场演示通常是最好的。
- 如果他仍然坚持,并提出了正当的商业理由-现在是你做出判断的时候了:这个网站低到没有价值吗?这真的是一个有效的商业案例吗?对你来说够好了吗?您是否可以考虑其他风险,这些风险会超过有效的业务原因?(当然,客户不是恶意网站,但那是duh)。如果是这样,就直接去吧。把必要的过程落实到位(在这个假设的情况下)是不值得付出努力、磨擦和浪费的。在这种情况下,任何其他的决定都是一种不好的权衡。
所以,底线和实际答案——用一个简单的对称算法加密它,用强大的ACL保护加密密钥,最好是dpapi之类的,将其记录下来,并让客户(足够资深的人做出决定)在其上签字。好的。好啊。
中途站怎么样?
使用强加密存储密码,不启用重置。
不要重置密码,而是允许发送一次性密码(第一次登录时必须更改)。然后,让用户更改为他们想要的任何密码(如果他们选择了前一个密码)。
您可以"出售"这个作为重置密码的安全机制。
允许用户检索原始密码的唯一方法是使用用户自己的公钥对其进行加密。只有那个用户才能解密他们的密码。
所以步骤是:
如果用户随后请求他们的密码,您将使用加密(而不是散列)密码进行响应。如果用户不希望将来能够检索其密码(他们只能将其重置为服务生成的密码),则可以跳过步骤3和7。
我认为你应该问自己的真正问题是:"我怎样才能更好地说服别人?"
我也有同样的问题。同样的,我总是认为有人入侵我的系统,这不是"如果"的问题,而是"何时"的问题。
所以,当我必须做一个网站,需要存储一个可恢复的机密信息,如信用卡或密码,我做的是:
- 加密方式:openssl_encrypt(string$data,string$method,string$password)
- PHP手册。
- 数据ARG:
- 敏感信息(如用户密码)
- 必要时序列化,例如,如果信息是多个敏感信息之类的数据数组
- 密码参数:使用只有用户知道的信息,例如:
- 用户牌照
- 社会保障号
- 用户电话号码
- 用户母亲名称
- 在注册时通过电子邮件和/或短信发送的随机字符串。
- 方法:
- 选择一种密码方法,如"aes-256-cbc"
- 不要将"password"参数中使用的信息存储在数据库(或系统中的任何位置)中。
当需要检索此数据时,只需使用"openssl_decrypt()"函数并询问用户答案。例如:"要接收您的密码,请回答以下问题:您的手机号码是多少?"
PS 1:不要将数据库中存储的数据用作密码。如果您需要存储用户手机号码,则不要使用此信息对数据进行编码。总是使用只有用户知道的信息,或者对于非亲属来说很难知道的信息。
PS 2:对于信用卡信息,比如"一键购买",我要做的就是使用登录密码。此密码在数据库(sha1、md5等)中散列,但在登录时,我将纯文本密码存储在会话或非持久(即内存)安全cookie中。这个普通的密码永远不会保存在数据库中,实际上它总是保存在内存中,在节的末尾被销毁。当用户单击"一键购买"按钮时,系统使用此密码。如果用户使用Facebook、Twitter等服务登录,那么我会在购买时再次提示密码(好的,这不是完全的"点击"),或者使用用户用于登录的服务的某些数据(如Facebook ID)。
安全凭据不是二进制操作:安全/不安全。安全性是关于风险评估的,是一个连续的过程。安全狂热者不喜欢这样想,但丑陋的事实是,没有什么是绝对安全的。具有严格密码要求的哈希密码、DNA样本和视网膜扫描更安全,但代价是开发和用户体验。明文密码的安全性要低得多,但实施起来要便宜得多(但应该避免)。一天结束时,它归结为违约的成本/收益分析。您可以根据要保护的数据的值及其时间值来实现安全性。
一个人的密码进入野外要花多少钱?在给定系统中模拟的成本是多少?对于联邦调查局的电脑来说,成本可能是巨大的。对于Bob的一次性五页网站来说,成本可以忽略不计。专业人员为客户提供选项,当涉及到安全性时,会列出任何实现的优势和风险。这是双重的,所以如果客户要求一些东西,可能会使他们面临风险,因为他们没有遵守行业标准。如果客户特别要求双向加密,我将确保您记录您的反对意见,但这不会阻止您以您知道的最佳方式实施。最后,这是客户的钱。是的,你应该推动使用单向散列,但要说这绝对是唯一的选择,任何其他不道德的东西都是胡说八道。
如果您使用双向加密存储密码,那么安全性就归结为密钥管理。Windows提供了将对证书私钥的访问限制为管理帐户和密码的机制。如果您在其他平台上托管,则需要查看这些平台上有哪些可用选项。正如其他人所建议的,您可以使用非对称加密。
我知道没有法律(英国的数据保护法)特别规定密码必须使用单向散列存储。这些法律中唯一的要求就是采取合理的安全措施。如果对数据库的访问受到限制,即使是纯文本密码也可以在这种限制下合法地进行限定。
然而,这也带来了另一个方面:法律优先权。如果法律优先权建议在构建系统的行业中必须使用单向散列,那么这是完全不同的。这就是你用来说服客户的弹药。除此之外,最好的建议是提供一个合理的风险评估,记录您的反对意见,并以最安全的方式实施系统,您可以给出客户的要求。
将用户的安全问题的答案作为加密密钥的一部分,不要将安全问题的答案存储为纯文本(改为哈希)
我以实现多因素身份验证系统为生,所以对我来说,很自然地认为你可以重置或重建密码,同时临时使用一个较小的因素来验证用户的重置/娱乐工作流。尤其是使用OTP(一次性密码)作为一些附加因素,如果时间窗口短于建议的工作流,则可以降低大部分风险。我们已经为智能手机(大多数用户已经随身携带了一整天)实现了软件OTP生成器,并取得了巨大的成功。在出现有关商业插件的抱怨之前,我要说的是,我们可以降低在密码不是唯一用于验证用户身份的因素时,使其易于检索或重置的固有风险。我承认,对于站点场景中的密码重用,情况仍然不理想,因为用户会坚持使用原始密码,因为他/她也希望打开其他站点,但您可以尝试以最安全的方式传递重构的密码(htpps和HTML上的谨慎外观)。
刚刚遇到了这个有趣而热烈的讨论。但最让我吃惊的是,人们对以下基本问题的关注微乎其微:
- Q1。用户坚持使用纯文本存储密码的实际原因是什么?为什么它有这么大的价值?
用户年龄大或年轻的信息并不能真正回答这个问题。但是,如果不正确理解客户的顾虑,如何做出业务决策呢?
为什么重要?因为如果客户请求的真正原因是系统非常难以使用,那么解决确切原因可能会解决实际问题?
因为我没有这些信息,也不能和那些客户交谈,所以我只能猜测:这是关于可用性的,见上文。
我看到的另一个问题是:
- Q2。如果用户首先不记得密码,为什么旧密码很重要?
这是可能的答案。如果你有一只叫"Miaumiau"的猫,用它的名字作为密码,但忘记了,你更愿意被提醒它是什么,还是宁愿被发送类似"zy*rw(ew)"的邮件?
另一个可能的原因是用户认为很难找到新密码!因此,把旧密码发回去给她一个幻想,让她再次从痛苦的工作中解脱出来。
我只是想了解原因。但无论原因是什么,都是必须解决的原因而不是原因。
作为用户,我希望事情简单!我不想努力工作!
如果我登录到一个新闻网站阅读报纸,我想输入1111作为密码,并通过!!!!
我知道这是不安全的,但我关心的是有人访问我的"帐户"吗?是的,他也能看新闻!
网站是否存储我的"私人"信息?我今天读的新闻?那是网站的问题,不是我的问题!网站是否向经过身份验证的用户显示私人信息?那就不要一开始就表现出来!
这只是为了展示用户对问题的态度。
总而言之,我不认为这是如何"安全"地存储纯文本密码的问题(我们知道这是不可能的),而是如何解决客户的实际问题。
对不起,但是只要你有办法破解他们的密码,就不可能是安全的。苦战,如果你输了,西亚。
处理丢失/忘记的密码:
任何人都不应该能够恢复密码。
如果用户忘记了密码,他们必须至少知道自己的用户名或电子邮件地址。根据请求,在用户表中生成一个guid,并将包含guid作为参数的链接的电子邮件发送到用户的电子邮件地址。
链接后面的页面验证参数guid是否真的存在(可能带有一些超时逻辑),并向用户请求一个新密码。
如果您需要热线帮助用户,请将一些角色添加到您的赠款模型中,并允许热线角色作为标识用户临时登录。记录所有此类热线登录。例如,Bugzilla为管理员提供了这样的模拟功能。
如果您不能仅仅拒绝存储可恢复密码的要求,那么作为您的反参数,这样做如何?
我们可以正确地散列密码并为用户构建重置机制,或者从系统中删除所有个人身份信息。您可以使用电子邮件地址设置用户首选项,但这就是问题所在。使用cookie在以后访问时自动提取首选项,并在合理的时间段后丢弃数据。
密码策略经常忽略的一个选项是是否真正需要密码。如果你的密码政策唯一能做的就是引起客户服务电话,也许你可以摆脱它。
注册后,在加密和丢失明文密码之前,通过电子邮件发送它怎么样?我见过很多网站都这样做,从用户的电子邮件中获取密码比把它留在服务器/comp上更安全。
用户真的需要恢复(例如被告知)他们忘记的密码是什么,还是仅仅需要进入系统?如果他们真正想要的是登录密码,为什么不让一个程序简单地将旧密码(无论是什么)更改为支持人员可以提供给丢失密码的人的新密码?
我曾经使用过这样的系统。支持人员无法知道当前密码是什么,但可以将其重置为新值。当然,所有这些重置都应该记录在某个地方,好的做法是向用户生成一封电子邮件,告诉他密码已经重置。
另一种可能是同时拥有两个允许访问帐户的密码。一个是用户管理的"普通"密码,另一个类似于仅由支持人员知道的、对所有用户都相同的骨架/主密钥。这样,当用户遇到问题时,支持人员可以使用主密钥登录到该帐户,并帮助用户将密码更改为任何内容。不用说,系统也应该记录所有使用主密钥的登录。作为一个额外的措施,无论何时使用主密钥,您都可以验证支持人员的凭证。
-编辑-回应关于没有主密钥的评论:我同意这是坏的,正如我认为允许用户以外的任何人访问用户的帐户是坏的一样。如果您考虑这个问题,整个前提是客户授权了一个高度受损的安全环境。
万能钥匙不必像最初看起来那么糟糕。我曾经在一家国防工厂工作,在那里他们意识到主机操作员在某些情况下需要"特殊访问"。他们只需把特殊密码放在一个密封的信封里,然后用胶带贴在操作台上。要使用密码(操作员不知道),他必须打开信封。每次换班时,当班主管的工作之一是查看信封是否已打开,是否立即(由另一个部门)更改密码,并将新密码放入新信封,然后重新开始整个过程。操作人员会被问到他为什么打开它,这一事件会被记录在案。
虽然这不是我要设计的程序,但它确实起到了作用,并提供了良好的问责制。所有的东西都被记录和审查过,加上所有的操作人员都得到了国防部的秘密许可,我们从来没有被滥用过。
由于审查和监督,所有运营商都知道,如果他们滥用打开信封的特权,他们将被立即解雇,并可能受到刑事起诉。
所以我想真正的答案是,如果一个人想做正确的事情,他可以雇佣他们可以信任的人,做背景调查,行使适当的管理监督和责任。
但是,如果这个可怜的家伙的客户有良好的管理,他们不会首先要求这样一个安全综合解决方案,现在他们会吗?
从我对这个主题的一点了解来看,我相信如果你正在建立一个有登录/密码的网站,那么你甚至不应该在你的服务器上看到纯文本密码。在密码离开客户机之前,应该对其进行哈希处理,并可能进行盐渍处理。
如果您从未看到明文密码,那么检索问题就不会出现。
此外,我(从网络上)了解到(据称)一些算法(如MD5)不再被认为是安全的。我无法判断我自己,但这是值得考虑的事情。
正常情况下,对用户密码进行salt和hash操作。当登录用户时,允许两个用户的密码(在salt/hashing之后),但也允许用户输入的内容也匹配。
这允许用户输入他们的密码,但也允许他们输入他们的密码的salt/hashed版本,这是有人从数据库中读取的。
基本上,使salted/hashed密码也是一个"纯文本"密码。
您可能没有考虑的另一个选项是允许通过电子邮件进行操作。这有点麻烦,但是我为一个客户机实现了这一点,它需要用户"在其系统之外"查看(只读)系统的某些部分。例如:
正如您在评论中所提到的,如果电子邮件被泄露,这将不起作用,但它确实可以解决@joachim关于不想重置密码的评论。最终,他们将不得不使用密码重置,但他们可以在更方便的时候,或者在管理员或朋友的帮助下,根据需要进行重置。
此解决方案的一个转折点是将操作请求发送给第三方受信任的管理员。对于老年人、精神障碍者、非常年轻或其他困惑的用户来说,这是最好的方法。当然,这需要信任的管理员来支持这些人的操作。
在独立服务器上打开数据库,并为每个需要此功能的Web服务器提供加密的远程连接。它不必是关系数据库,也可以是具有ftp访问权的文件系统,使用文件夹和文件而不是表和行。如果可以,请授予Web服务器只写权限。
将不可检索的密码加密存储在站点的数据库中(让我们称之为"pass-a"),就像普通人一样。在每个新用户(或密码更改)上,在远程数据库中存储密码的纯拷贝。使用服务器的ID、用户的ID和"pass-a"作为此密码的组合键。您甚至可以对密码使用双向加密,以便在夜间更好地睡眠。
现在,为了让某人同时获得密码和上下文(站点ID+用户ID+"pass-a"),他必须:
您可以控制密码检索服务的可访问性(仅将其公开为安全的Web服务,每天仅允许一定数量的密码检索,手动执行等),甚至为此"特殊安全安排"收取额外费用。密码检索数据库服务器是相当隐藏的,因为它不提供许多功能,并且可以更好地保护(您可以严格定制权限、进程和服务)。
总而言之,你让黑客的工作更加困难。在任何一台服务器上发生安全漏洞的可能性都是相同的,但是有意义的数据(帐户和密码的匹配)将很难组装起来。