如果密码存储在安全的数据库中,为什么还要加密?


78

我有一个网络服务。现在,我的密码以纯文本格式存储在服务器上的MySQL表中。我知道这不是最佳做法,这就是为什么我正在努力。

如果密码存储在安全的数据库中,为什么还要加密?我意识到,如果有人入侵我的数据库,他们将获得每个人的密码。但是如果有人进入我的数据库,我还有其他问题,例如删除数据。

我能想到的情况是您被黑了。您从几个小时前还原了数据库,一切都很好。但是,如果您的密码是纯文本...小偷拥有所有密码,则必须重置所有密码。麻烦您的用户。

如果密码已加密,则可以还原到以前的数据库。这是正确的想法吗?


124
我会更进一步。对其进行加密还不够。您想对它进行哈希处理。这样,您甚至都无法知道用户的明文密码是什么。
2014年

67
@Santa散列密码是不够的。您必须添加一些盐以使配方足够好...
Bakuriu 2014年

16
请查看以下相关Security.StackExchange帖子:如何安全地对密码进行哈希处理?
阿迪2014年

10
分散的DBA说...从用户中选择*,然后出售该列表以支付严重性费用。没有什么是安全的。
乔恩·雷诺2014年

Answers:


194

首先,您应该拥有比只读更多的自由访问权限。黑客可能会访问您的数据,但无法对其进行编辑。

但是,更重要的是,这与您无关。如果某人具有对数据库的完全访问权限,您可能会被搞砸,这一事实是无关紧要的。更重要的是用户的数据。

如果您恢复数据库,则黑客仍然有权访问您的用户帐户。

还有谁知道呢?如果他们在Google使用相同的密码怎么办?还是贝宝?如果这样可以使黑客访问其母亲的姓氏或信用卡的后4位数字,该怎么办?

如果这使他们进入其他帐户怎么办?不要让黑客通过用户支持系统来获取更多信息

只是...只是不。这是您用户的私人信息,您不需要能够看到它。这也是你的声誉。加密。

编辑:一个额外的注释,以保存任何未来的读者从阅读每个答案和评论...

如果要进行加密(从最严格的意义上讲),则需要使用公钥/私钥对,这很好,但是会使您和您的用户的生活更加困难。

一种更简单有效的解决方案是对密码进行随机加盐哈希处理。仅靠散列是不够的。如果您的用户使用通用密码,则它将显示在反向哈希表中,通过简单的Internet搜索即可轻松获得。


89
或者更好,将其哈希!
Blorgbeard 2014年

29
这个。“如果有人进入我的数据库,我还会遇到其他问题”。这是您的数据库,如果被黑客入侵,您预计会遇到问题。但是,通过存储纯文本密码,您可能会给所有用户所有其他帐户带来麻烦。您认为每个网站上实际上有多少人使用不同的密码?
Carson63000

13
请按照Blorgbeard的建议,也许可以阅读这个。当您的Web服务器受到威胁时,加密密码不能提供保护。解密密码的密钥必须存储在服务器上的某个位置。散列密码意味着即使有人可以完全访问计算机,他们也无法轻松恢复密码。
Slicedpan 2014年

7
如果密码对您的系统没有任何价值,为什么还要加密密码?除了进行比较之外,您还需要在什么时间解密密码?@pdr,您不应该告诉OP进行加密,而应该告诉他进行加盐和哈希处理。
NobleUplift 2014年

4
您还希望散列其密码恢复问题的答案。否则,这些密码也可以用于进入其他站点,就像密码一样。
Zan Lynx 2014年

64

如果遭到黑客入侵,则可以从备份中还原站点并进行修复。 但是黑客仍然拥有每个人帐户的密码! 有记录在案的现实世界中的例子(Sony,已链接),在这些例子中,如果正确地对哈希表进行哈希处理和添加盐分,那么快速保护和恢复服务就容易得多。

考虑到这一假设,假设您被黑客入侵,并设计备份策略并加密所有敏感数据可能是一个好主意。而且不仅仅是需要防御的黑客。不满,不诚实或无知的员工可能会泄露纯文本密码。

如果不进行散列,则必须禁用所有人的访问权限,直到他们更改密码为止(即使可能,这也将使所有人头疼)。如果密码已经过哈希处理,那么您可以恢复该Web服务,这将使攻击者更难于访问人们的帐户。

正确散列和加盐的密码基本上是单向的。您不能轻易地从哈希密码中猜出密码。甚至您,由于服务提供商将无法猜测,您只能重置它。

另外,正如Elin所说,请勿尝试滚动自己的哈希(或加密)。使用标准库。



13
+1表示不满的员工。当您是一家单人商店或一家小型公司时,很容易忽略,但是最终您将需要有人来处理未经您亲自审查的数据。

2
编写foreach遍历用户列表然后对他们的密码进行哈希处理仅需几分钟,而坦率地说4000几乎没有什么用。php.net/manual/en/function.hash.php
Elin

3
您可以在术语“加密”与“哈希和盐” @ david25272之间进行切换。不要混淆两者,它们是完全不同的。现在,OP正在寻找一种加密算法,而不是哈希算法。另外,它是“盐和哈希”,而不是“哈希和盐”。哈希后不能撒盐。
NobleUplift 2014年

1
另外@phpmysqlguy,请阅读我的答案以获取有关盐腌和哈希算法的建议。
NobleUplift 2014年

36

但是如果有人进入我的数据库,我还有其他问题,即删除数据。

这与遇到的问题无关,而与所有其他用户可能遇到的问题有关。这是关于消除对网站上的工作人员滥用存储在其中的数据的诱惑(甚至更糟的是,潜在的责任)。

看到,即使人们应该在不同的系统上使用不同的密码,事实是事实并非如此

...而且由于很容易对密码进行散列,因此您没有理由不遵循行业最佳实践。


9
您认为我认为最重要的一点是: 和您的工作人员不应访问用户密码。谁在乎黑客,是那些持有与用户有关的数据的人。
亚当·戴维斯

1
+1是因为您作为开发人员/管理员不能访问用户密码。这本身就足够了。
马特

21

诸如删除数据之类的引人注目的攻击通常是业余爱好者的事,并且是您最少的担心。有经验的攻击者要做的第一件事就是尝试获得合法的访问权限,因此,即使您修补了他使用的原始漏洞,他也仍然可以进入。他将尽一切可能避免引起对他的注意,直到他完成他想要的。通过不打乱密码,您可能会使他的工作容易得多。您也使检测和隔离他未来的恶意行为变得更加困难。

另外,并非所有妥协都可以让您完全使用shell。如果攻击者使用的漏洞只是users表上的只读SQL注入,该怎么办?保留密码不变,这给了他几乎完全的访问权限。

除此之外,其他答案还提供了有关您有责任保护用户数据的原因。我的意思是,损失的不仅仅是您的用户。


18

我必须在这里就问题本身的谬误发表答案。您在询问是否应加密密码。没有人会加密密码。除了Firefox Sync和Roboform之类的服务和程序,其唯一目的是对密码进行加密,没有人可以拒绝。

让我们看一下定义:

在密码术中,加密是对消息(或信息)进行编码的过程,以使只有授权方才能读取它。

和哈希:

哈希函数是将任意长度的数据映射到固定长度的数据的任何算法。

换句话说,加密是双向转换,而哈希是单向转换,因此除非您稍后解密以查看它们,否则这不是加密。

另外,不要只是哈希,散列密码之前,请先阅读整个页面。

至于OP现在正在研究的哈希算法,我建议使用任何高端SHA-2变量,例如SHA-384或SHA-512。

并确保使用回合哈希。不要散列一次,散列多次。

考虑阅读此页面以进一步保护您的登录过程。

其次,您的数据库永远不可能足够安全。始终会有安全漏洞和不断变化的风险。您应该遵循墨菲定律,并始终为最糟糕的情况做准备。

pdr提出其他观点恰恰是我要说的:对每个网站使用相同密码的人,利用社会工程学获取更多信息的黑客等等。


+1哈希再加盐。破解散列无盐是SOOO容易。
代码Maverick

3
您知道彩虹表@CodeMaverick另一侧的内容吗?一壶金。
NobleUplift 2014年

在密码散列的上下文中,MD5除了快速之外没有其他已知漏洞,这也适用于SHA-2。使用缓慢,反复建设是远远超过了MD5选择SHA-2更重要。
CodesInChaos

4
“你哈希的密码之前,请阅读此整个页面” -这页提到,您应该使用散列的回合,但已专门设计了一种散列方法是有够慢的需要,如PBKDF2。
jhominal

2
使用SCrypt或PBKDF2,它们在内存或CPU方面的执行成本都非常高。使用您存储在用户记录中的随机生成的Salt。不要执行多轮哈希运算,这只会导致冲突问题。
tom.dietrich 2014年

14

这里有一个重要的原则在讨论。只有一个从事任何业务的人都知道用户密码。那是用户。不是他们的妻子/丈夫,他们的医生甚至是牧师。

它绝对不包括负责他们使用的服务的程序员,数据库管理员或系统技术人员。这就带来了挑战,因为程序员确实有责任接收证明用户实际上知道密码的证据,这纯粹是解决不小的问题。

纯粹的解决方案是具有一种机制,使用户面临一些新的且不可预测的数据的挑战,然后必须基于此数据及其密码返回响应。一种实现方式是要求用户使用他们的数字签名对一些新生成的数据进行数字签名,并且我们可以从数学上证明他们使用了与最初创建帐户时相同的加密密钥对。

实际上,纯解决方案需要大量的客户端基础结构和处理,并且对于许多网站而言,这通常不适用于受保护的数据。

一个更常见的解决方案是:

在应用程序中首次接收到密码时,该密码将与应用程序的随机“ salt”值一起传递给哈希函数。

然后,原始字符串将在内存中被覆盖,从那时起,加盐的哈希将存储在数据库中或与数据库记录进行比较。

这里提供安全性的关键方面是:

  1. 哈希的知识不会直接提供身份验证。
  2. 从哈希反向计算密码是不切实际的。
  3. 使用彩虹表(一长串密码及其计算出的哈希值)变得更具挑战性,因为生成的哈希值取决于用户名和密码。

6
通常,最好使用随机盐代替用户名。
CodesInChaos 2014年

哇,好极了@CodesInChaos。我在第一次阅读问题时没有注意到这一点。是的,盐应该是随机产生的。它不一定是存储在MySQL中的疯狂Blob(这将是不好的,因为那样的话它就不能移植了)。否则,+ 1表示只有用户应该知道用户的密码。
NobleUplift 2014年

好的,更新的答案表明该应用程序具有其自己的随机盐值。
Michael Shaw

4
不,应用程序没有一个盐值要么。每个存储的哈希应该有一个不同的,高度随机的盐值。(您将盐存储在该哈希值旁边。)这就是防止统计攻击的原因。如果您对整个应用程序使用相同的哈希,则相同的纯文本哈希将具有相同的值。这远比使用用户名作为哈希值更糟糕。
Ben Voigt 2014年

它不是Web服务,但SSH密钥对身份验证确实使用“纯”解决方案,其中服务器存储公用密钥,而用户使用私钥进行身份验证。
cpast 2014年

10

您需要对口令进行“加密”(实际上是“散列”,以获得适当的散列概念)作为第二层防御:这是为了防止攻击者(以只读方式查看数据库)升级进行读写访问,并确切地开始更改数据。在现实世界中会发生只读的部分破坏,例如,通过具有只读访问权限的帐户的某些SQL注入攻击,或者通过从垃圾箱中回收废弃的硬盘或旧的备份磁带,来发生这种情况。我在那儿写了很长的篇幅。

至于散列密码的正确方法,请参见此答案。这包括盐,迭代,以及最重要的,不是你自己发明的算法(自制加密是一种肯定后患无穷)。


+1用于了解加密和哈希之间的区别。
NobleUplift

8

我不会重复别人说的话,但是假设您拥有PHP 5.3.8或更高版本,则应该使用PHP本机bcrypt来存储密码。这是内置在PHP中的。如果您有PHP 5.5,则可以使用最佳的可用密码常数。您还可以使用库使5.3.8或更高的行为类似于5.5。

堆栈溢出问题如何使用bcrypt在PHP中对密码进行哈希处理?解释它,那里的其他答复解释了更多。请不要自欺欺人。


2
不幸的是,我正在使用PHP 5.3.3,所以您的建议将不适用
phpmysqlguy 2014年

4
5.3.3到5.3.8的升级多少钱?
gbjbaanb 2014年

您有机会使用Red Hat吗?因为他们已将修复程序反向移植到bcrypt。如果不是,则使用SHA256代替brcypt。
Elin 2014年

1
加密和散列是不同的东西。散列密码,请勿加密。您永远不需要了解他们。您只需要用户能够使用密码来证明他/她是谁。哈希(加盐)可以做到这一点。加密,特别是 对称加密是错误的,因为它允许恢复密码。
Paul de Vrieze 2014年

我要添加的一件事是,关于PHP 5.5+中password_hash()函数的好处是,它默认处理盐析等。在此之前,您需要继续使用像ircmaxell的库那样的东西对其进行反向移植(他编写了5.5实现)。不要以为自己会随机产生盐。这是非常非常困难的,最好留给专家;确实很容易获得可利用的随机但非统一结果。
Elin 2014年

7

由于该答案中所述的原因,我同意pdr的答案。

我将添加以下内容:您应该这样做,因为它易于执行,并且通常被认为是任何应用程序的最佳实践。更具体地说,在写入任何持久性存储之前,应始终对密码进行加密和哈希处理。这是关于加盐和选择良好的加密哈希(还提供几种流行语言的免费源代码)的重要性的很好的参考:https : //crackstation.net/hashing-security.htm

少量的额外开发时间非常值得,它为您的用户提供了保护,并赢得了您作为开发人员的声誉。


+1既提到了加盐和哈希,也没有提及加密,这甚至都不属于这个问题。
NobleUplift 2014年

2

我能想到的情况是您被黑了。

您需要考虑的另一种情况是:某人让您的DBA滑倒(或者其他任何人可以在您的DB上运行选择查询)$ 100,以向他们提供用户密码。或由社会工程师来实习。

然后,他们使用这些密码登录到用户的Gmail ...或商业网站...(因为人们……我们不应该这么聪明-并在各个网站上使用相同的密码)。

然后,愤怒的用户起诉您的公司以公开其密码。


NOBODY(包括您公司中的人员)应该能够读取纯文本密码。曾经 没有合法的业务或技术需求。


2

首先,即使数据库管理员也不应看到用户的密码。如果管理员决定查看密码并登录其用户帐户,则对它们进行哈希处理将防止这种情况。


1
这并没有增加任何值得在先前答案中发布的内容
gnat 2014年

3
+1。他实际上说的是“散列”,而不是像许多其他加密方法一样加密。此外,他直接与OP发生冲突,OP说他希望密码以明文形式登录到其他用户的帐户。
NobleUplift 2014年

0

好吧,令人惊讶的是没有人提到这件事,但是数据库的物理安全性又如何呢?

您可能设置了世界上最好的IT安全性,但这并不能阻止任何人可以物理访问您的存储介质。当您的团队今天下午赢得超级碗比赛,并且办公室/托管服务提供商所在的城市闹市区爆发小规模骚乱时,会发生什么情况?(考虑到西雅图与丹佛是美国的两个大型IT领域,我认为这是不合理的)。暴民闯入您的建筑物,当当局不知所措时,有人抢了您的一些硬件,上面有一个包含明文密码的数据库?

当美联储出现并抓住您的设备时,会发生什么?然后,美联储使用这些密码来调查您的客户,尽管他们没有做错任何事情。然后他们意识到是让他们脆弱。

当您的IT部门在按计划进行替换之前忘记擦拭保存数据库的旧RAID驱动器,然后将旧驱动器“分发”给实习生,然后他们的宿舍室友找到留下的东西,并弄清楚他们可以“清除”时,会发生什么情况?出售”,而它却从未追溯到他们?

当您的数据库服务器损坏主板,IT将映像还原到新服务器并将旧服务器的“遗体”扔到回收堆中时,会发生什么?这些驱动器仍然很好,并且数据仍然存在。

任何体面的架构师都知道,防火墙和操作策略不会在以后“加强”安全性。从一开始就必须将安全性作为设计的基本部分,这意味着密码是单向散列的,绝不会在未加密的情况下传输(即使在您自己的数据中心内部),并且永远不可恢复。可以检索的任何内容都会受到损害。


-1

撇开数据库被黑客入侵的情况来看:作为客户,我不想让您知道我的密码。我知道您可以在请求中轻松获取密码,但是当您不愿意使用它随时查询时,我会感觉更好。


1
实际上,如果OP更进一步,并使用JavaScript进行加密,则哈希将通过网络发送,并且在请求中永远不会被看到。
NobleUplift 2014年

1
在这种情况下,攻击者也只需要通过网络发送哈希即可。哈希只是一个看似但未加密的密码,不是吗?(编辑:不是每次都必须用不同的盐腌制,并且盐来自服务器。我想)
RemcoGerlich 2014年

1
@RemcoGerlich关键概念被称为nonce,用于避免重放攻击

-1

如果密码以纯文本格式存储,则意味着用户以及有权访问该表的任何人都知道密码。关于实现用户和密码的整个想法是,出于隐私和安全方面的考虑,确保系统中的某个会话属于该用户。

如果一群人知道用户名/密码,那么毫无疑问地无法识别一个人,这将为身份盗窃,欺诈创造许多可能的情况。

这就是使用非对称加密协议存储密码的原因,以确保您可以验证密码而又无法读取它们。


2
谁使用非对称加密存储密码?那就是公钥密码术,这意味着即使我加密了密码,如果有人获得了我的私钥,它也可以被解密和读取。通过散列,我只有我自己知道密码(除非我将其写下或放入密码管理器中,该密码管理器实际上是非对称加密的)。
NobleUplift 2014年

请检查Wikipedia页面上的公共密钥加密: en.wikipedia.org/wiki/Public-key_cryptography “公共密钥加密,也称为非对称加密,”
Alpha1983

2
……是的,我这么说using asymmetric encryption? That's public-key cryptography。你想说啥?
NobleUplift 2014年

-1

我认为这个问题有一个根本性的缺陷。事实是,没有“安全数据库”之类的东西。应当认为,您的系统中存在一些漏洞,这些漏洞可能允许恶意用户访问您服务器上的任意数据。Heartbleed是一个很好的例子,这是一种在研究人员发现之前就已经存在了两年多的野蛮漏洞。您可能已经做了所有您知道该怎么做才能保护数据的事情,但是您无法说明服务器上正在使用的所有其他软件以及它们交互的复杂方式。

如果有人对您感兴趣,您被黑。重要的是,尽最大努力防止被黑客入侵,同时通过尽可能多地设置障碍来减轻发生这种情况时所造成的损害。散列密码。设置起来并不难,并且您由于不认真对待用户的隐私而给用户带来了损害。认为您比YahooSonyTarget等公司都遭到了黑客攻击时,能以某种方式更好地抵御恶意攻击是一种骄傲。


1
这似乎并没有提供超过14个先前答案的实质性内容
gnat 2014年

我不同意,否则我不会发布。除了阻止人们参与之外,我不确定您是否会发表负面评论,这会增加对话。
lobati 2014年

好吧,不知道您是否在发布答案之前就已经阅读了其他答案,但是根据我的阅读,这里的所有观点已经在其他地方提出了(并且根据我的阅读得到了更好的介绍)。例如,关于这个问题的缺陷点已经取得了2个多月前在这个这个答案。关于散列密码的要点至少在其他7个答案中提出。关于备份和解决系统其他部分中可能出现的问题的观点也是很久以前提出的。等等
2014年

链接的谬论点与我的不同。他们说的是散列与加密在含义上的区别,而我说的是认为数据库可以被认为是“安全的”是一个谬误。在讨论其他软件及其交互不安全时,我仍然看不到其他答案,也没有对备份提出任何意见。
lobati 2014年

“假设您被黑客入侵”-这是2个月前发布的答案中的拼写方式
gnat 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.