当我继续建立越来越多的网站和网络应用程序时,我经常被要求存储用户的密码,如果/当用户有问题时,它们可以被检索(要么通过电子邮件发送一个忘记密码的链接,通过电话等),当我可以与这种做法作斗争时,我做了大量的“额外”编程,使密码重置和管理协助成为可能,而不存储他们的实际密码。
当我无法对抗它(或无法获胜)时,我总是以某种方式对密码进行编码,这样至少它不会以明文形式存储在数据库中——尽管我知道如果我的数据库被黑客攻击,罪犯不需要花费太多时间就能破解密码,所以这让我感到不舒服。
在一个完美的世界里,人们会经常更新密码,而不会在许多不同的网站上重复密码——不幸的是,我知道很多人都有相同的工作/家庭/电子邮件/银行密码,甚至在他们需要帮助的时候免费给我。如果我的数据库安全程序因为某种原因失败了,我不想成为他们财务崩溃的罪魁祸首。
从道德和伦理上讲,我觉得我有责任保护一些用户的生活,即使他们对他们的生活不那么尊重。
我确信有许多方法和论点可以用于盐散列和不同的编码选项,但当您必须存储它们时,是否存在单一的“最佳实践”?在几乎所有的情况下,我使用PHP和MySQL,如果这使任何不同的方式,我应该处理的细节。
Bounty的其他信息
我想澄清的是,我知道这不是你想要做的事情,在大多数情况下,拒绝这样做是最好的。然而,我并不是在寻求关于采用这种方法的优点的说教,我是在寻找如果你确实采用这种方法,应该采取的最佳步骤。
在下面的注释中,我指出了主要面向老年人、智障人士或非常年轻的人的网站,当他们被要求执行安全密码恢复程序时,他们会感到困惑。尽管在这些情况下,我们可能会发现这很简单,但有些用户需要额外的帮助,要么让服务技术人员帮助他们进入系统,要么通过电子邮件/直接显示给他们。
在这样的系统中,如果用户没有得到这种级别的访问帮助,来自这些人口统计数据的流失率可能会阻碍应用程序,所以请在回答时考虑到这样的设置。
谢谢大家
这是一个有趣的问题,有很多争论,我很喜欢。最后,我选择了一个答案,它既保留了密码安全性(我不必保留纯文本或可恢复的密码),又使我指定的用户群能够登录到一个系统,而不存在我在正常密码恢复中发现的主要缺陷。
像往常一样,由于不同的原因,大约有5个答案我想标记为正确,但我必须选择最好的一个——其余的都是+1。谢谢大家!
同时,感谢Stack社区中为这个问题投票和/或将其标记为最喜欢的人。我把获得100票作为一种赞美,希望这个讨论能帮助到和我有同样担忧的人。
在回答这个问题时,已经有很多关于用户安全问题的讨论,但我想再提一下好处。到目前为止,我还没有看到在系统中存储可恢复密码的合法好处。考虑一下:
通过电子邮件发送密码对用户有好处吗?不。他们从一次性密码重置链接中获益更多,这有望让他们选择一个他们能记住的密码。
在屏幕上显示密码对用户有好处吗?不,原因和上面一样;他们应该选择一个新密码。
让技术支持人员告诉用户密码对用户有好处吗?没有;同样,如果支持人员认为用户的密码请求已经过正确验证,那么为用户提供新密码和更改密码的机会对用户更有利。此外,电话支持比自动密码重置更昂贵,所以该公司也没有受益。
从可恢复的密码中获益的似乎只有那些怀有恶意的人,或者那些需要第三方密码交换的糟糕api的支持者(请永远不要使用这些api !)也许你可以通过如实向客户陈述公司存储可恢复密码没有获得任何好处,只会承担责任来赢得争论。
从这类请求的字里行间,您会发现客户端可能根本不理解,甚至根本不关心密码是如何管理的。他们真正想要的是一个对用户来说并不难的认证系统。所以,除了告诉他们其实他们并不想要可恢复的密码之外,你还应该为他们提供一些让认证过程不那么痛苦的方法,尤其是如果你不需要像银行这样的高安全级别:
允许用户使用他们的电子邮件地址作为用户名。我见过无数用户忘记自己的用户名,但很少有人忘记自己的电子邮件地址。
提供OpenID,让第三方支付用户遗忘的成本。
放宽密码限制。我敢肯定,当一些网站因为“不能使用特殊字符”或“您的密码太长”或“您的密码必须以字母开头”之类无用的要求而不允许您使用首选密码时,我们都非常恼火。此外,如果易用性比密码强度更重要,您甚至可以通过允许更短的密码或不要求混合字符类来放松不愚蠢的要求。随着限制的放松,用户将更有可能使用他们不会忘记的密码。
不要让密码过期。
允许用户重新使用旧密码。
允许用户选择自己的密码重置问题。
但如果你出于某种原因(请告诉我们原因)真的,真的,真的需要一个可恢复的密码,你可以通过给他们一个非密码认证系统来保护用户,以免他们的其他在线帐户受到潜在的威胁。因为人们已经熟悉用户名/密码系统,这是一个行之有效的解决方案,这将是最后的手段,但肯定有很多创造性的替代密码的方法:
让用户选择一个数字引脚,最好不要是4位,最好只在防止暴力尝试的情况下。
让用户选择一个只有他们自己知道的简短答案的问题,这个问题永远不会改变,他们会一直记住,而且他们不介意其他人发现。
让用户输入一个用户名,然后画一个容易记住的形状,并有足够的排列来防止猜测(看看这张G1如何解锁手机的漂亮照片)。
对于一个儿童网站,你可以根据用户名(有点像身份)自动生成一个模糊的生物,并要求用户给这个生物一个秘密的名字。然后他们会被提示输入该生物的秘密名称来登录。
刚刚看到这个有趣而热烈的讨论。
最让我惊讶的是,很少有人关注以下基本问题:
Q1。用户坚持访问纯文本存储的密码的实际原因是什么?为什么它这么有价值?
用户年龄大或小的信息并不能真正回答这个问题。但是,如果没有正确理解客户的关注点,如何做出业务决策呢?
为什么这很重要呢?
因为如果客户要求的真正原因是系统难以使用,那么解决具体原因可能会解决实际问题?
由于我没有这些信息,也无法与这些客户交谈,我只能猜测:这是关于可用性的,见上文。
我看到的另一个问题是:
Q2。如果用户一开始就不记得密码,为什么旧密码很重要?
这是可能的答案。
如果你有一只叫“miaumiau”的猫,用她的名字作为密码,但忘记了,你是更愿意被提醒它是什么,还是更愿意被发送像“#zy*RW(ew)”这样的信息?
另一个可能的原因是,用户认为想出一个新密码是一项艰巨的工作!所以,把旧密码发送回去给她一种错觉,让她不用再去做那件痛苦的工作了。
我只是想知道原因。但无论原因是什么,必须解决的是原因而不是原因。
作为用户,我希望事情简单!我不想努力工作!
如果我登录一个新闻网站看报纸,我想输入1111作为密码,然后就可以通过了!!
我知道这是不安全的,但我在乎别人访问我的“帐户”吗?是的,他也会看新闻!
网站是否存储我的“私人”信息?
我今天读的新闻?
那就是网站的问题,不是我的!
站点是否向已验证的用户显示私人信息?
那就先别表现出来!
这只是为了说明用户对问题的态度。
总之,我不认为这是一个如何“安全地”存储纯文本密码的问题(我们知道这是不可能的),而是如何解决客户实际关心的问题。
用另一种方法或角度来解决这个问题怎么样?询问为什么密码必须是明文:如果是为了让用户可以检索密码,那么严格地说,您实际上不需要检索他们设置的密码(他们不记得它是什么),您需要能够为他们提供一个他们可以使用的密码。
想想看:如果用户需要检索密码,那是因为他们忘记了密码。在这种情况下,新密码和旧密码一样有效。但是,目前使用的常用密码重置机制的缺点之一是,在重置操作中生成的密码通常是一堆随机字符,因此用户很难正确地输入它们,除非他们复制-粘贴。对于不太精明的电脑用户来说,这可能是个问题。
解决这个问题的一种方法是提供自动生成的密码,这些密码或多或少是自然语言文本。虽然自然语言字符串可能没有相同长度的随机字符字符串的熵,但没有人说你的自动生成的密码只需要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%的密码被破解:唯一可能发生的事情就是有人用我的名字发垃圾邮件或发帖。那样不太好,但他们又不会侵入我的银行账户。然而,鉴于许多人在他们的论坛网站上使用的密码与他们的银行账户密码(可能还有国家安全数据库密码)相同,我认为最好将这些“低价值”密码作为不可恢复的密码来处理。