我应该如何以道德的方式处理用户密码存储以便以后进行明文检索?
随着我继续构build越来越多的网站和Web应用程序,我经常被要求存储用户的密码,以便在用户遇到问题时可以检索用户的密码(通过电子邮件发送一个被遗忘的密码链接,电话等)当我可以对付这种做法苦涩的时候,我做了很多“额外的”编程,使密码重置和pipe理协助成为可能,而不需要存储他们的实际密码。
当我不能对抗(或不能赢)时,我总是以某种方式对密码进行编码,至less它不会作为明文存储在数据库中 – 尽pipe我知道如果我的DB被黑客入侵罪魁祸首并不需要太多的破解密码,这让我感到不舒服。
在一个完美的世界里,人们会经常更新密码,而不是在许多不同的网站上复制它们,不幸的是,我知道很多人有相同的工作/家庭/电子邮件/银行密码,甚至在他们需要帮助时也可以自由地给我。 如果我的数据库安全程序出于某种原因失败,我不希望成为他们财务危机的责任人。
在道义上和道德上,我觉得对于一些用户保护他们的生计负有责任,即使他们不那么尊重地对待他们。 我确信有很多途径可以为腌制和不同的编码select提供方法和论据,但是当你需要存储它们时,是否有一个“最佳实践”? 在几乎所有的情况下,我使用的是PHP和MySQL,如果这在我处理细节的方式上有所不同的话。
附加信息赏金
我想澄清一下,我知道这不是你想要做的事情,在大多数情况下拒绝这样做是最好的。 但是,我不想寻求采取这种方法的优点,我正在寻找采取这种方法的最佳步骤。
在下面的一个注释中,我指出,当被要求执行安全的密码恢复程序时,主要针对老年人,精神障碍者或非常年轻的网站可能会让人感到困惑。 尽pipe在这种情况下,我们可能会发现它简单而平凡,但有些用户需要服务技术人员帮助他们进入系统或直接通过电子邮件发送/显示给他们。
在这样的系统中,如果用户没有获得这个级别的访问帮助,那么这些人口统计学的损耗率可能会阻碍应用程序,所以请回答这样的设置。
谢谢大家
这是一个有趣的问题,有很多争论,我很享受。 最后,我select了一个答案,既保留密码的安全性(我将不必保持纯文本或可恢复的密码),但也使我指定的用户群login到系统没有我发现的主要缺点正常的密码恢复。
和往常一样,大概有5个答案,我想标记为不同的原因是正确的,但是我必须select最好的答案 – 其余的答案都是+1。 感谢大家!
此外,感谢Stack社区中的每个人都为此问题投了赞成票并将其标记为最爱。 我以百分之一百的票数作为赞美,希望这次讨论能够帮助其他人也有同样的担忧。
如何在这个问题上采取另一种方法或angular度? 问为什么密码需要明文:如果是这样,以便用户可以检索密码,严格来说,你真的不需要检索他们设置的密码(他们不记得它是什么),你需要能够给他们一个密码,他们可以使用 。
想一想:如果用户需要检索密码,那是因为他们已经忘记了密码。 在这种情况下,新密码与旧密码一样好。 但是,目前常见的密码重置机制的缺点之一是在重置操作中产生的密码通常是一串随机字符,所以用户难以正确input,除非他们复制n-糊。 这可能是一个不太懂电脑的用户的问题。
解决这个问题的方法之一就是提供自动生成的密码,它们或多或less是自然语言文本。 虽然自然语言string可能没有相同长度的随机string所具有的熵,但没有任何说自动生成的密码只需要8(或10或12)个字符。 通过将几个随机单词串联在一起(在它们之间留下一个空格,以便任何可以阅读的人仍然可以识别和键入)来获得高熵自动生成的密码短语。 六个不同长度的随机单词可能比10个随机字符更容易正确和自信地input,并且它们也可以具有更高的熵。 例如,从大写,小写,数字和10个标点符号(总共72个有效符号)中随机抽取的10个字符的密码的熵将具有61.7比特的熵。 使用7776字(作为Diceware使用)的字典可以随机select一个六字密码,密码将有一个77.4位的熵。 有关更多信息,请参阅Diceware常见问题解答 。
-
与约77位熵密码:“承认散文flare表急性天赋”
-
一个有大约74位熵的密码:“K:&$ R ^ tt〜qkD”
我知道我更喜欢input这个短语,而使用复制粘贴,这个短语不是那么容易使用密码,所以在那里没有任何损失。 当然,如果您的网站(或任何受保护的资产)不需要77位熵来自动生成密码短语,那么可以生成更less的单词(我相信您的用户会喜欢)。
我了解有密码保护资产的论据,这些资产确实没有很高的价值,所以违反密码可能不是世界末日。 例如,如果我在各种网站上使用的密码有80%被破坏,我可能不会在意:所有可能发生的事情都是一些垃圾邮件或以我的名义发布一段时间。 这不会很好,但不是他们会闯入我的银行账户。 但是,鉴于很多人在他们的networking论坛网站上使用的密码和他们的银行帐户(可能是国家安全数据库)使用相同的密码,所以我认为最好是将那些“低价值”的密码作为非-recoverable。
想象一下,有人委托build造一座大型build筑 – 一个酒吧,让我们说 – 和下面的谈话发生:
build筑师: 对于这样大小和容量的build筑,你需要在这里,这里和这里消防。
客户: 不,这太复杂和昂贵了,我不想要任何侧门或后门。
build筑师: 主席先生,消防通道不是可选的,按照城市的防火规定是必需的。
客户: 我没有付钱争辩。 只要做我所问。
那么build筑师会问,如何在没有起火的情况下道德build造这座build筑?
在build筑和工程行业,谈话最有可能是这样结束的:
build筑师: 这座build筑不能没有消防通道。 你可以去任何其他有执照的专业人士,他会告诉你同样的事情。 现在我要走了; 当你准备好合作的时候给我打电话。
计算机编程可能不是一个有执照的行业,但人们往往似乎很想知道为什么我们的专业不像民用或机械工程师那样得到同样的尊重。 这些职业,当交给垃圾(或直接危险)的要求,将简单地拒绝。 他们知道这不是一个借口,说:“我尽力而为,但他坚持,我必须做他的话。” 他们可能因此而失去执照。
我不知道你或你的客户是否是任何上市公司的一部分,但以任何可恢复的forms存储密码将导致你失败几种不同types的安全审计。 这个问题并不是一个能够访问数据库的“黑客”恢复密码的难度。 绝大多数的安全威胁是内部的。 你需要保护的是一些不满的员工走出所有的密码,并将其出售给出价最高的人。 使用非对称encryption并将私钥存储在单独的数据库中完全不能防止这种情况; 总会有人访问私人数据库,这是一个严重的安全风险。
以可恢复的forms存储密码没有道德或负责任的方式。 期。
你可以用公钥encryption密码+盐。 对于login只是检查存储的值是否等于从用户input+盐计算的值。 如果有一段时间,密码需要以明文方式恢复,则可以使用私钥进行手动或半自动解密。 私钥可以被存储在别处,并且可以被对称地encryption(然后需要人工交互来解密密码)。
我认为这实际上类似于Windows恢复代理的工作方式。
- 密码被encryption存储
- 人们可以在不解密的情况下login到明文
- 密码可以恢复为纯文本,但只能使用私钥,可以存储在系统之外(如果需要,可以在银行保险箱中)。
不要放弃。 你可以用来说服你的客户的武器是不可否认的。 如果您可以通过任何机制重build用户密码,那么您已经为其客户提供了合法的不可否认机制,并且可以否认依赖该密码的任何交易,因为供应商无法certificate他们没有重build密码并通过自己的交易。 如果密码被正确地存储为摘要而不是密文,那么这是不可能的,无论是最终客户自己执行交易还是违背了密码的注意义务。 在任何一种情况下,都会使他承担责任。 我已经处理了那些数额达数亿美元的案例。 不是你想错的东西。
您不能道德地存储密码以供日后明文检索。 就这么简单。 即使乔恩Skeet不能道德地存储密码为以后的明文检索。 如果您的用户可以用某种方式以纯文本的方式获取密码,那么黑客也可能会在您的代码中发现安全漏洞。 这不仅仅是一个用户的密码被盗用,而是所有这些。
如果您的客户遇到问题,请告诉他们,存储密码是可以接受的,这是违法的。 在英国,无论如何,1998年的“数据保护法”(特别是附录1第二部分第9段)要求数据控制人员使用适当的技术措施保证个人数据的安全,同时考虑到如果数据遭到破坏可能造成的伤害 – 对于在站点间共享密码的用户来说,这可能是相当可观的。 如果他们在处理这个问题时仍然有困难,请将它们指向一些真实的例子,比如这个例子。
允许用户恢复login的最简单的方法是通过电子邮件发送给他们一个自动login的链接,并将他们直接带到一个可以select新密码的页面。 创build一个原型并将其展示给他们。
这里有几篇关于这个主题的博文:
- http://jamesmckay.net/2009/09/if-you-are-saving-passwords-in-clear-text-you-are-probably-breaking-the-law/
- http://jamesmckay.net/2008/06/easy-login-recovery-without-compromising-security/
更新:我们现在开始看到针对未能妥善保护用户密码的公司提起诉讼和起诉。 例如: LinkedIn打了500万美元的集体诉讼 ; 索尼被PlayStation数据破解罚款25万英镑 。 如果我没有记错的话,LinkedIn实际上是在encryption用户的密码,但是它使用的encryptionfunction太弱,无法生效。
阅读完这部分内容后:
在下面的一个注释中,我指出,当被要求执行安全的密码恢复程序时,主要针对老年人,精神障碍者或非常年轻的网站可能会让人感到困惑。 尽pipe在这种情况下,我们可能会发现它简单而平凡,但有些用户需要服务技术人员帮助他们进入系统或直接通过电子邮件发送/显示给他们。
在这样的系统中,如果用户没有获得这个级别的访问帮助,那么这些人口统计学的损耗率可能会使应用程序停滞不前,所以请回答一下这样的设置。
我还想知道这些要求中的任何一个是否要求可检索的密码系统。 比如:Mabel阿姨打来电话,说:“你的networking程序不工作,我不知道我的密码”。 “OK”表示客服人员说:“让我查一下一些细节,然后给你一个新的密码 ,当你下次login的时候会问你是否要保存密码或者改成你能记得的密码更容易“。
然后,系统设置为知道何时发生密码重置,并显示“您要保留新密码还是select新密码”消息。
如果说电脑识字率低于被告知旧密码,情况会如何? 而客户服务人员可以起来恶作剧,数据库本身是更安全的,以防万一它被破坏。
评论我的build议有什么不好,我会build议一个解决scheme,实际上做你最初想要的。
迈克尔·布鲁克斯(Michael Brooks)一直对CWE-257发表了相当的声音 – 无论你使用什么方法,你(pipe理员)都可以恢复密码。 那么这些选项如何呢?
- 用别人的公钥encryption密码 – 一些外部的权限。 这样,你不能亲自重build,用户将不得不去该外部的权力,并要求恢复他们的密码。
- 使用从第二个密码生成的密钥encryption密码。 做这个encryption客户端,永远不会传输到服务器。 然后,为了恢复,再次通过从其input中重新生成密钥来进行解密客户端。 无可否认,这种方法基本上是使用第二个密码,但是你总是可以告诉他们写下来,或者使用旧的安全问题方法。
我认为1.是更好的select,因为它使您能够指定客户公司内的某个人持有私钥。 确保他们自己生成密钥,并将其存储在安全的指令中。您甚至可以通过select仅encryption和提供密码中的某些字符给内部第三方来增加安全性,以便他们必须破解密码以猜测它。 提供这些字符给用户,他们可能会记得它是什么!
对于这个问题,用户对于安全问题已经有很多的讨论,但是我想补充一些好处。 到目前为止,我还没有看到在系统上存储可恢复密码的合法利益 。 考虑这个:
- 用户的密码是否通过电子邮件发送给他们? 不。他们从一次性使用密码重设链接中获得更多的好处,希望能让他们select一个他们会记住的密码。
- 用户在屏幕上显示的密码是否受益? 不,出于同样的原因, 他们应该select一个新的密码。
- 用户是否有从支持人员向用户说出密码的好处? 没有; 再次,如果支持人员认为用户对其密码的请求是正确authentication的,则给用户的好处是给予新密码并有机会改变它。 另外,电话支持比自动密码重置成本更高,所以公司也不会受益。
似乎唯一可以从可恢复密码中受益的是那些具有恶意意图的用户,或者是需要第三方密码交换(请不要使用这些API)的可怜的API支持者。 也许你可以通过如实告诉你的客户赢得你的观点,即公司通过存储可恢复的密码不会获得任何好处和责任 。
从这些types的请求之间进行阅读,你会发现你的客户可能不理解甚至实际上甚至在乎如何pipe理密码。 他们真正想要的是一个对用户来说不那么难的authentication系统 。 因此,除了告诉他们实际上不需要可恢复的密码之外,还应该为他们提供一些方法来使authentication过程变得不那么痛苦,特别是如果您不需要银行的严格安全级别:
- 允许用户使用他们的电子邮件地址作为他们的用户名。 我已经看到无数用户忘记用户名的情况,但很less有人忘记他们的电子邮件地址。
- 提供OpenID并让第三方支付用户遗忘的费用。
- 缓解密码限制。 我敢肯定,当一些网站由于诸如“你不能使用特殊字符”或“你的密码太长”或“你的密码必须启动”等无用的要求而不允许你的首选密码的时候,我们都感到非常恼火带着一封信。“ 而且,如果易用性比密码强度更受关注,则可以通过允许更短的密码或不需要混合的字符类来放松非愚蠢的要求。 随着限制放宽,用户将更有可能使用他们不会忘记的密码。
- 不要过期密码。
- 允许用户重用旧密码。
- 允许用户select自己的密码重置问题。
但是,如果您出于某种原因(并请告诉我们原因) 确实需要能够拥有可恢复的密码,那么您可以通过向用户提供非密码的方式来防止潜在的其他在线帐户的泄露,基于authentication的系统。 因为人们已经熟悉用户名/密码系统,并且他们是一个行之有效的解决scheme,这将是最后的手段,但肯定有很多创造性的替代密码:
- 让用户select一个数字引脚,最好不要input4位数字,最好只有在蛮力企图被保护的情况下。
- 让用户select一个简短的答案,只有他们知道答案,永远不会改变,他们会永远记住,他们不介意别人发现。
- 让用户input一个用户名,然后画出一个易于记忆的形状,以便进行充分的排列,以防止猜测(请参阅G1的这个用于解锁手机的巧妙照片 )。
- 对于儿童网站,您可以根据用户名(类似于identicon)自动生成模糊生物,并要求用户给该生物一个秘密名称。 然后可以提示他们input生物的秘密名称来login。
根据我对这个问题的评论:
重要的一点几乎每个人都掩盖了…我最初的反应与@Michael Brooks非常相似,直到我意识到像@stefanw一样,这里的问题已经被打破了要求,但是这些都是他们自己的。
但是,那么对我来说可能不是这样! 这里缺less的一点是应用程序资产的潜在价值 。 简而言之,对于一个低价值的系统,一个完全安全的authentication机制,涉及到所有的过程,将是矫枉过正的,而且是错误的安全select。
显然,对银行来说,“最佳做法”是必须的,没有办法从伦理上违反CWE-257。 但是很容易想到低价值的系统,这是不值得的(但是仍然需要一个简单的密码)。
重要的是要记住,真正的安全专业知识是find适当的权衡,而不是教条式地吐出任何人都可以在线阅读的“最佳实践”。
因此,我build议另一个解决scheme:
根据系统的价值, 只有在系统价值适中且没有“昂贵”的资产(包括身份本身)的情况下,还有一些有效的业务要求使得正确的处理变得不可能(或者足够困难/昂贵) ,而客户意识到所有的注意事项…
那么简单地允许可逆encryption就可以了,没有特殊的箍环可以跳过。
因为实施起来非常简单/便宜(甚至考虑可通过的密钥pipe理),所以我只是停下来说不要encryption,而且它提供了一些保护(比实现它更多的成本)。 此外,它的价值在于如何向用户提供原始密码,无论是通过电子邮件,在屏幕上显示等。
由于这里的假设是被盗密码的价值(即使是合计)是相当低的,这些解决scheme中的任何一个都是有效的。
由于讨论正在进行中,实际上几个热闹的讨论,在不同的post和单独的评论主题上,我会加上一些澄清,并回应一些在这里提到的很好的观点。
首先,我想这里的每个人都很清楚,允许用户的原始密码被检索出来就是坏习惯,而且通常不是一个好主意。 这完全没有争议。
另外,我会强调,在很多情况下,最不好的情况是,这确实是错误的,甚至是犯规,讨厌和丑陋 。
但问题的关键是围绕这个原则 ,是否有什么情况可能不必要这样做,如果是的话,怎样才能以最恰当的方式来做到这一点。
现在,正如@Thomas,@sfussenegger和其他几个人所提到的那样,回答这个问题的唯一正确方法就是对任何给定的(或假设的)情况进行彻底的风险分析 ,了解到底有多危险,值得保护多less还有哪些缓解措施可以起到保护作用。
不,这不是stream行语,这是真正的安全专家的基本,最重要的工具之一。 最佳实践很好(通常作为缺乏经验和黑客的指导方针),然后在深思熟虑的风险分析接pipe之后。
你知道,这很有趣 – 我一直认为自己是安全狂的一员,不知怎的,我和那些所谓的“安全专家”相反……事实是 – 因为我是一个狂热的人,和一个真正的现实安全专家 – 我不相信在没有那么重要的风险分析的情况下出现 “最佳实践”教条(或CWE)。
“要小心安全狂,他们很快就会把所有东西都用在工具带上,而不知道他们正在防御的是什么实际问题,更多的安全措施并不一定就是安全的。”
风险分析和真正的安全狂热者将指出基于风险,潜在损失,可能的威胁,补充性缓解措施等的智慧,基于价值/风险的折衷。任何不能指出合理风险分析的“安全专家”根据他们的build议,或支持逻辑权衡,而宁可吹嘘教条和CWE,甚至没有理解如何进行风险分析,只是安全黑客,他们的专长是不值得他们打印的卫生纸。
的确,那就是我们如何得到机场安全的荒谬。
但是,在我们谈到在这种情况下作出适当的权衡之前,让我们来看看明显的风险(显然,因为我们没有关于这种情况的所有背景信息,我们都是假设 – 因为问题是假设情况可能会有…)
让我们假设一个低价值的系统,但不是那么繁杂,以至于它是公共访问 – 系统所有者想要防止偶然的冒充,但“高”的安全性不像易用性那么重要。 (是的,这是一个合理的权衡,以接受风险,任何精通脚本kiddie可以入侵网站…等等,是不是现在stream行的APT?)
举个例子,假设我正在为一个大型的家庭聚会安排一个简单的网站,让大家集思广益,讨论我们今年的露营之旅。 我不那么担心一些匿名的黑客,或者甚至表弟弗雷德一再提出build议,要回到万艾曼纳比基利基湖,因为我是关于埃玛姨妈不能在需要时login的。 现在,作为核物理学家的埃尔玛婶婶在记忆密码,甚至根本不使用电脑方面都不是很擅长……所以我想要消除她所有可能的摩擦。 再次,我不担心黑客,我只是不想愚蠢的错误login错误 – 我想知道谁来,什么他们想要的。
无论如何。
那么,如果我们对密码进行对称encryption,而不是使用单向散列,那么我们的主要风险是什么?
- 冒充用户? 不,我已经接受了这个风险,没有意思。
- 邪恶的pipe理员? 好吧,也许…但是,再次,我不在乎是否有人可以模仿另一个用户,内部或不… …无论如何,无论如何,一个恶意的pipe理员会得到你的密码 – 如果你的pipe理员不好,它的游戏无论如何。
- 另一个被提出的问题是,身份实际上是在几个系统之间共享的。 啊! 这是一个非常有趣的风险,需要仔细观察。
首先让我断言,这不是实际共享的身份 ,而是certificate或authentication凭证。 好吧,由于共享密码将有效地允许我进入另一个系统(比如我的银行帐户,或者gmail),这实际上是同一个身份,所以它只是语义上的……除非它不是 。 在这种情况下(尽pipe可能会有第三方身份识别系统,比如OAuth,它仍然与本系统中的身份分离),但是在每个系统中都会单独pipe理身份。
因此,这里的风险的核心是用户愿意将他(同一)密码input到几个不同的系统 – 现在,我(pipe理员)或我的网站的任何其他黑客将有权访问姨妈的密码核导弹现场。
嗯。
这里有什么东西似乎对你?
这应该。
让我们从保护核导弹系统不是我的责任的事实开始,我只是build立一个frakkin家庭出游网站(为我的家人)。 那么谁的责任呢? 呃…核导弹系统怎么样? 咄。
其次,如果我想窃取某人的密码(知道在安全站点之间重复使用相同密码的人,以及不安全的密码),为什么我会打扰您的网站? 还是与你的对称encryption挣扎? Goshdarnitall,我可以把自己的简单的网站 ,让用户注册接收非常重要的新闻,他们想要什么…帕夫Presto,我“偷走”他们的密码。
是的,用户教育总是回来咬我们,不是吗?
而且你无法做到这一点…即使你想在你的网站上密码,并且做了TSA可以想到的所有其他的事情,你也可以保护他们的密码不是一次 ,如果他们要保留乱七八糟的把他们的密码塞进他们遇到的每一个网站。 不要偶尔打扰尝试。
换句话说, 你不拥有他们的密码 ,所以不要像你那样行事。
所以,我的亲爱的安全专家,作为一个老太太曾经问温迪的,“哪里有风险?
还有几点要回答上面提出的一些问题:
- CWE不是法律,法规,甚至是标准。 这是一个共同的弱点 ,即“最佳实践”的反面。
- 共同认同的问题是一个实际问题,但在这里被反对者误解(或歪曲)。 这是一个共享身份的问题(!),而不是破解低价值系统上的密码。 如果您在低价值系统和高价值系统之间共享密码,问题已经在那里了!
- 由此,以前的观点实际上指出,对于这些低价值系统和高价值的银行系统,都不愿意使用OAuth等。
- 我知道这仅仅是一个例子,但是(可悲的是)联邦调查局系统并不是最安全的。 不像你的猫的博客服务器,但也不超过一些更安全的银行。
- encryption密钥的分裂知识或双重控制不仅仅发生在军事上,事实上PCI-DSS现在基本上都要求所有的商家都这样做,所以它现在不再那么实际(如果价值合理的话)。
- 对那些抱怨这样的问题的人来说,是什么让开发人员的职业看起来如此糟糕:这是类似这样的答案,这使得安全行业更加糟糕。 再一次,以业务为中心的风险分析是需要的,否则你会使自己无用。 除了错误之外。
- 我想这就是为什么不聘请一个普通的开发人员,把更多的安全责任放在他身上,而没有经过培训,思考不同,寻找正确的权衡。 没有冒犯,对你们这里的人来说,我是全力以赴的,但更多的训练是为了。
呼。 多长时间…
但是要回答你原来的问题,@Shane:
- 向客户解释做事情的正确方法。
- 如果他仍然坚持,再解释一下,坚持,争辩。 发脾气,如果需要的话。
- 向他解释业务风险。 细节是好的,数字更好,现场演示通常是最好的。
- 如果他仍然坚持,并提出有效的商业理由 – 现在是时候做一个判断电话:
这个网站是低价值吗? 这真的是一个有效的商业案例吗? 对你来说够好吗? 是否没有其他风险可以考虑,这将超过有效的商业原因? (当然,客户端不是一个恶意网站,但那是呃)。
如果是这样,就直接前进。 在这个假设的情况下,不必付出努力,摩擦和失去使用的必要过程。 任何其他决定(再次,在这种情况下)是一个坏的折衷。
因此,底线和实际答案 – 用一个简单的对称algorithm对它进行encryption,用强ACL,最好是DPAPI或类似的方法来保护encryption密钥,logging下来,并让客户(有足够资深的客户做出这个决定)签字它。
How about a halfway house?
Store the passwords with a strong encryption, and don't enable resets.
Instead of resetting passwords, allow sending a one-time password (that has to be changed as soon as the first logon occurs). Let the user then change to whatever password they want (the previous one, if they choose).
You can "sell" this as a secure mechanism for resetting passwords.
The only way to allow a user to retrieve their original password, is to encrypt it with the user's own public key. Only that user can then decrypt their password.
So the steps would be:
- User registers on your site (over SSL of course) without yet setting a password. Log them in automatically or provide a temporary password.
- You offer to store their public PGP key for future password retrieval.
- They upload their public PGP key.
- You ask them to set a new password.
- They submit their password.
- 你使用最好的密码散列algorithm(例如bcrypt)来散列密码。 在validation下一次login时使用这个。
- 您使用公钥对密码进行encryption,然后单独存储。
如果用户要求input密码,则用encryption(不是散列)密码进行回应。 如果用户不希望能够在将来检索他们的密码(他们只能将其重置为服务生成的密码),则可以跳过步骤3和7。
我想你应该问自己的真正问题是:“我怎样才能更好地说服人呢?
我有同样的问题。 同样的,我总是认为有人破解我的系统,不是“如果”而是“何时”的问题。
所以,当我必须做一个网站需要存储一个可恢复的机密信息,如信用卡或密码,我做的是:
- encryption与: openssl_encrypt (string$数据,string$方法,string$密码)
- PHP手册 。
- 数据arg :
- 敏感信息(如用户密码)
- 如果需要序列化,例如,如果信息是像多个敏感信息的数据arrays
- 密码arg :使用只有用户知道的信息:
- 用户牌照
- 社会安全号码
- 用户电话号码
- 用户的母亲的名字
- 一个随机的string通过电子邮件发送和/或通过短信在注册时间
- 方法arg :
- select一种密码方法,如“aes-256-cbc”
- 切勿将“密码”参数中使用的信息存储在数据库(或系统中的任何位置)
当需要检索这些数据时,只需使用“openssl_decrypt()”函数并询问用户的答案。 例如: “要收到您的密码,请回答问题:您的手机号码是什么?
PS 1 :从不使用存储在数据库中的数据作为密码。 如果您需要存储用户手机号码,则不要使用此信息对数据进行编码。 始终使用只有用户知道的信息,或者知道某个非亲属很难的信息。
PS 2 :对于信用卡信息,如“一键购买”,我所做的是使用login密码。 这个密码在数据库(sha1,md5等)中被散列化,但是在login的时候,我把纯文本密码存储在会话中或者非持久性(即在内存中)的安全cookie中。 这个简单的密码永远不会停留在数据库中,事实上它始终保留在内存中,在部分结束时被破坏。 当用户点击“一键购买”button时,系统使用该密码。 如果用户使用Facebook,Twitter等服务login,那么我在购买时再次提示密码(好吧,这不是一个完全的“点击”),或者使用用户用来login的服务的一些数据(如facebook的id)。
保护凭据不是一个二进制操作:安全/不安全。 安全是关于风险评估的,并且是连续统一的。 安全狂热者不喜欢这样想,但丑陋的事实是,没有什么是完全安全的。 对严格密码要求的散列密码,DNA样本和视网膜扫描更安全,但是以开发和用户体验为代价。 明文密码安全性要差得多,但实施起来要便宜(但应该避免)。 在这一天结束时,归结为违约的成本/收益分析。 您根据所保护的数据的值及其时间值来实施安全性。
某人的密码到野外的费用是多less? 给定系统中扮演的成本是多less? 联邦调查局的电脑,成本可能是巨大的。 对于鲍勃的一次性五页网站来说,成本可以忽略不计。 一位专业人员为他们的客户提供select,而在安全方面,则列出了任何实施的优势和风险。 如果客户因为不注意行业标准而要求提供某些可能使其处于危险之中的情况,则情况会更加严重。 如果客户特别要求双向encryption,我会确保你logging你的反对意见,但是这不应该阻止你以最好的方式实施。 在一天结束的时候,这是客户的钱。 是的,你应该推动使用单向散列,但是说这绝对是唯一的select,其他任何事情都是不道德的。
如果您使用双向encryption存储密码,则安全性都归功于密钥pipe理。 Windows提供了一些机制来将对证书私钥的访问限制为pipe理帐户和密码。 如果您在其他平台上托pipe,则需要查看可用的选项。 正如其他人所build议的,您可以使用非对称encryption。
没有任何法律(英国的“数据保护法”),我知道明确指出密码必须使用单向散列存储。 任何这些法律中唯一的要求就是为了安全采取合理的步骤。 如果对数据库的访问受到限制,即使明文密码也可以在这种限制下合法地获得资格。
但是,这确实揭示了另外一个方面:法律优先。 如果法律优先权表明您必须使用您的系统所在行业的单向散列,那么这是完全不同的。 这是你用来说服你的客户的弹药。 除此之外,提供合理风险评估的最佳build议,logging您的反对意见,并以最安全的方式实施系统,以满足客户的要求。
将用户的安全问题的答案作为encryption密钥的一部分,不要将安全问题的答案存储为纯文本(而是使用散列)
为了生活,我实现了多重身份validation系统,所以对于我来说,认为您可以重置或重build密码是很自然的事情,而临时只使用一个较less的因素来validation用户的身份,只需要重置/重build工作stream程。 特别是使用OTP(一次性密码)作为一些附加因素,如果时间窗口短于build议的工作stream程,可以减轻很多风险。 我们已经实施了用于智能手机的软件OTP生成器(大多数用户已经整天携带自己),取得了巨大的成功。 在投诉出现商业插件之前,我所说的是,我们可以降低保密密码容易检索或重置的固有风险,而这些风险并不是用于authentication用户的唯一因素。 我承认,对于站点场景中的密码重用,情况还是不太好,因为用户会坚持要有原始密码,因为他/她也想打开其他站点,但是可以尝试将重build的密码最安全的方法(在html上htpps和谨慎的外观)。
对不起,只要你有一些解码密码的方法,就没有办法保证它的安全。 战斗痛苦,如果你输了,CYA。
刚刚遇到这个有趣和热烈的讨论。 但是,最让我感到意外的是,对以下基本问题的关注却很less:
- Q1。 用户坚持访问纯文本存储密码的实际原因是什么? 为什么这么有价值?
用户年老的信息并不能真正回答这个问题。 但是,如果没有正确理解客户的关注,如何做出商业决策呢?
现在为什么重要? 因为如果客户要求的真正原因是难以使用的系统,那么解决确切的原因就能解决实际问题?
由于我没有这些信息,也无法与这些客户交谈,所以我只能猜测:关于可用性,请参阅上文。
我见过的另一个问题是:
- Q2。 如果用户不记得密码,为什么旧密码很重要?
这里是可能的答案。 如果你有一只名叫“miaumiau”的猫,用她的名字作为密码,但忘记了你的意思,你更喜欢提醒它是什么,或者是发送一些像“#zy * RW(ew)?
另一个可能的原因是,用户认为这是一个艰辛的工作,想出一个新的密码! 因此,将旧密码发回给人的幻想是再次将她从痛苦的工作中拯救出来。
我只是想了解原因。 但无论是什么原因,这是不是原因必须解决的原因。
作为用户,我希望事情简单! 我不想努力工作!
如果我login新闻网站阅读报纸,我想input1111作为密码,并通过!
我知道这是不安全的,但是我有什么关心有人访问我的“帐户”? 是的,他也可以阅读这个消息!
该网站是否存储我的“私人”信息? 我今天读的消息? 那么这是网站的问题,不是我的! 该网站是否显示私密信息给authentication用户? 那就不要把它放在第一位!
这只是为了展示用户对问题的态度。
所以总的来说,我不觉得如何“安全地”存储纯文本密码(我们知道这是不可能的),而是如何解决客户的实际问题。
处理丢失/遗忘的密码:
没有人应该能够恢复密码。
如果用户忘记密码,他们至less必须知道他们的用户名或电子邮件地址。 根据请求,在Users表中生成一个GUID,并发送一个包含一个包含guid的链接的电子邮件作为用户电子邮件地址的参数。
链接后面的页面validation参数guid确实存在(可能有一些超时逻辑),并要求用户input新的密码。
如果您需要热线帮助用户,请向您的资助模式添加一些angular色,并允许热线angular色以标识用户的身份临时login。 logging所有这些热线login。 例如,Bugzilla为pipe理员提供了这种模拟function。
在注册之前通过电子邮件发送明文密码,然后将其encryption并丢失? 我看到很多网站都这样做,从用户的电子邮件中获取密码比将其保留在服务器/补丁上更安全。
如果你不能拒绝存储可恢复密码的要求,那么作为你的反驳论点呢。
我们可以正确地散列密码并为用户build立一个重置机制,或者我们可以从系统中删除所有的个人身份信息。 您可以使用电子邮件地址来设置用户首选项,但就是这样。 使用cookie自动调整未来访问的偏好设置,并在合理的时间段之后丢弃数据。
密码策略经常被忽视的一个选项是密码是否真的需要。 如果您的密码政策唯一的事情是造成客户服务电话,也许你可以摆脱它。
用户是否真的需要恢复(比如被告知)他们忘记的密码是什么,或者他们只需要能够进入系统? 如果他们真正想要的是一个login密码,为什么不有一个简单的改变旧密码(不pipe是什么)的例程到一个新的密码,支持人员可以给失去密码的人一个新的密码?
我已经与系统完成这个工作。 支持人员无法知道当前密码是什么,但可以将其重置为新的值。 当然,所有这些重置应该logging在某处,好的做法是生成一封电子邮件给用户,告诉他密码已被重置。
另一个可能性是有两个同时的密码允许访问一个帐户。 一个是用户pipe理的“正常”密码,另一个是仅由支持人员知道的骨架/主密钥,并且对于所有用户是相同的。 这样,当用户遇到问题时,支持人员可以使用主密钥login到帐户,并帮助用户更改密码。 不用说,所有使用主密钥的login都应该被系统logging下来。 作为额外的措施,无论何时使用主密钥,您也可以validation支持人员凭证。
-EDIT-为了回应关于没有主密钥的评论:我同意,这是不好的,因为我认为允许除了用户以外的任何人访问用户的帐户是不好的。 如果你看看这个问题,整个前提是客户要求一个高度妥协的安全环境。
万能钥匙不需要像最初看起来那么糟糕。 我曾经在一家防务工厂工作,他们认为大型计算机运营商需要在特定的场合“特殊访问”。 他们只是把密码放在一个密封的信封里,然后粘到操作员的桌子上。 要使用密码(操作员不知道),他必须打开信封。 每次轮class时,轮class主pipe的其中一项工作就是查看信封是否已经打开,如果是这样,则立即更改密码(由另一个部门),并将新密码放入新信封中,并且过程全部开始再次。 运营商将被质疑为什么他打开了它,事件将被logging在案。
虽然这不是我devise的程序,但它确实起作用,并提供了出色的问责制。 一切都被logging和审查,加上所有的运营商有国防部的秘密许可,我们从来没有任何虐待。
由于审查和监督,所有的经营者都知道,如果他们滥用信封的特权,他们立即被解雇和可能的刑事起诉。
所以我想真正的答案是,如果一个人想做正确的事情,雇用一个可以信任的人,做背景调查,并进行适当的pipe理监督和问责。
但是如果这个可怜的客户有一个好的pipe理层,他们本来不会要求这样一个安全的解决scheme,现在呢?
从我对这个主题的理解很less,我相信如果你正在build立一个带有login/密码的网站,那么你甚至都不应该在你的服务器上看到明文密码。 在离开客户端之前,密码应该被哈希,并且可能被腌制。
如果你从来没有看到明文密码,那么检索的问题就不会出现。
另外,我从网上收集到(据说)一些algorithm,如MD5,不再被认为是安全的。 我无法判断自己,但这是需要考虑的事情。
在独立服务器上打开一个数据库,并为每个需要此function的Web服务器提供encryption的远程连接。
它不一定是关系数据库,它可以是一个FTP访问的文件系统,使用文件夹和文件而不是表和行。
如果可以的话,给Web服务器写只读权限。
存储在网站的数据库中的密码不可检索的encryption(让我们称之为“pass-a”)像正常人一样:)
对每个新用户(或密码更改)在远程数据库中存储密码的普通副本。 使用服务器的ID,用户的ID和“pass-a”作为该密码的组合键。 你甚至可以使用密码上的双向encryption在晚上更好地睡觉。
现在为了让某人同时获得密码和上下文(网站ID +用户ID +“pass-a”),他必须:
- 攻击该网站的数据库,以获得(“传递一个”,用户ID)对或成对。
- 从一些configuration文件获取网站的ID
- find并入侵远程密码数据库。
您可以控制密码检索服务的可访问性(仅作为安全的Web服务提供,每天仅允许一定数量的密码检索,手动执行等),甚至为此“特殊安全安排”收取额外费用。
密码检索数据库服务器是相当隐蔽的,因为它不提供许多function,可以更好地保护(您可以定制权限,stream程和服务紧密)。
总而言之,你让黑客更加努力工作。 在任何一台服务器上发生安全漏洞的机会仍然是一样的,但是有意义的数据(帐户和密码匹配)将很难组装。
您可能没有考虑的另一个选项是允许通过电子邮件的行动。 这有点麻烦,但是我实现这个function的客户需要用户在系统外“查看”(只读)系统的某些部分。 例如:
- 一旦用户注册,他们有充分的权限(像一个普通的网站)。 注册必须包含电子邮件。
- 如果需要数据或操作,并且用户不记得他们的密码,他们仍然可以通过点击一个特殊的“ 给我发电子邮件许可 ”button,在常规的“ 提交 ”button旁边执行操作。
- 该请求然后被发送到具有超链接的电子邮件,询问他们是否想要执行该动作。 这与密码重置电子邮件链接类似,但不是重置密码,而是执行一次性操作 。
- 然后用户点击“是”,确认应该显示数据,或执行操作,显示数据等。
正如你在评论中提到的那样,如果电子邮件被泄露,这将不起作用,但是它确实解决了@joachim关于不想重置密码的评论。 最终,他们将不得不使用密码重设,但他们可以在更方便的时间,或在pipe理员或朋友的帮助下,根据需要做到这一点。
这种解决scheme的一个转折是将操作请求发送给第三方可信pipe理员。 对于老年人,精神病患者,年轻人或其他困惑的用户来说,这种方法效果最好。 当然,这需要一个值得信赖的pipe理员来支持他们的行动。
用户密码和正常一样。 当用户login时,同时允许用户的密码(salting / hashing后),而且允许用户input的内容也匹配。
这允许用户input他们的秘密密码,但是也允许他们input他们的密码的腌制/散列版本,这是人们从数据库中读取的。
基本上,使腌制/散列的密码也是一个“纯文本”的密码。