所谓哈希密码,指的是对口令进行一次性的加密处理而形成的杂乱字符串。这个加密的过程被认为是不可逆的,也就是说,从哈希串中是不可能还原出原口令的。虽然它不是唯一一个能够保证你的联网应用程序安全性的方法,但是它是众多安全保护措施中的一个,每一个有安全意识的开发者都应该考虑这个问题。

每当我们要讨论安全问题时,大家总会有一个疑问:我们所要防御的安全威胁到底是什么?对于密码哈希而言,答案肯定不会尽如人意:我们正在努力的是-当你网站数据库中存储的所有密码被盗窃之后,我们如何来缓解这类事件给人们带来的影响。通常情况下,如果攻击者成功进入了目标数据库之后,数据库中的许多数据都有可能被盗,而这也是每一个信息安全从业人员的噩梦。

哈希密码加密和破解浅析

我们现在来讨论一下,如果攻击者已经得到了你的密码数据库,会发生什么事情呢?攻击者能够利用这些数据来做些什么呢?实际上,所有相关的攻击都与恢复出用户密码有关,因为只有当获取到用户的密码之后,攻击者才可以进行下一步操作。
如果你的数据库中存储的是明文形式的密码,那么你就不用挣扎了。攻击者已经获取到了所有的用户密码,他可以开始为所欲为了。这简直太糟糕了。
尝试1#:简单的密码哈希
你可能会认为:“嗨,只要我们使用SHA256算法(或者SHA-3,或者其他的一些安全哈希算法)来对密码进行哈希处理,那么一切问题都不存在了。”如果你这样想的话,那么迟早都会出现问题。然而真实的情况往往会更加的复杂。
比如说,我们将现在的情况更加具体化。当你使用下列形式的哈希函数来对存储的密码进行处理时,会发生什么?
1P’=SHA256(P) (*)
其中,P为密码,P’为存储在数据库中的密码。
字典攻击
那么,假设攻击者已经获取到了所有存储在数据库中的密码了,而数据库中的密码仅仅使用了SHA256来进行哈希加密,正如我们在上面所列出的公式(*)。那么攻击者能够利用窃取来的密码数据做些什么呢?
首先,他可以获取一个记录了大量常用密码的字典文件,然后利用字典中的密码来依次进行尝试。也就是说,攻击者可以利用SHA256算法来对字典里的密码进行哈希处理,然后与数据库中存储的密码哈希进行对比(这也就是我们所说的“字典攻击”)。
请注意,使用简单的P’=SHA256(P)函数来进行哈希处理,也就意味着相同的“P”值在经过公式计算之后,将会得到相同的“P’”。也就是说,相同的密码在经过哈希处理之后,生成的密码哈希也是相同的。
这样一来,攻击者就可以利用SHA256算法预先对当前所有常用的密码进行哈希处理,然后在攻击者成功获取到了数据库中的数据之后,就可以利用这些预先计算好的密码哈希来进行对比了。相较于没有经过哈希处理的密码而言,密码哈希将会增加攻击者破解密码的难度。因此,对密码进行简单的哈希处理总是比没有进行哈希处理的密码要安全得多,但是这项技术仍然有很大的提升空间。

哈希密码加密和破解浅析
尝试2#:经过Salted的哈希
对相同的密码进行哈希处理之后,得到的密码哈希是相同的。为了解决这个问题,我们需要对密码哈希进行Salted处理,即“哈希加盐法”。
这种方式的工作机制为:当我们在计算相应“P’”之前,针对每一个用户的密码,我们都会存储一个相应的“S”值(即盐值)。当我们需要将用户密码存入数据库之前,我们需要利用下列公式来进行计算:
1P’=SHA256(S||P)
其中,“||”为连接的意思(例如字符串/数据块的级联)。
只要用户的“S”值与其他用户不同,那么即使不同用户使用的是相同的密码,计算出来的密码哈希值也不会相同。所以这也就意味着,攻击者预先计算出的密码哈希将无法使用,字典攻击也就失效了。实际上,我们所介绍的“哈希加盐法”还可以抵御一些其他的“预先计算”攻击,包括所谓的“彩虹表攻击”在内。
而我们需要考虑的另一个问题就是使用什么样的“Salt”。首先,每一个用户所使用的“S”值必须是独一无二的。这也就意味着,如果你所使用的随机“Salt”值足够长,你就不需要检查盐值的唯一性了。

对哈希函数进行离线暴力破解攻击
即便是我们在对密码进行哈希处理时加入了“Salt”,并且也仅用了字典密码。攻击者仍然有其他的方法来破解我们的密码数据库。
我所指的就是离线暴力破解攻击,需要注意的是,这种方式与在线暴力破解不同。当攻击者利用在线暴力破解的方式来攻击数据库时,攻击者只需要不断地尝试登录密码即可。但是我们可以设置登录失败次数限制或者密码尝试的时间间隔来防止这类攻击。

为了对密码数据进行离线暴力破解攻击,攻击者首先需要获取到存储了密码的数据库,或者至少是用户密码或者“salt”值的其中之一。在获得了这些信息之后,攻击者就可以利用公式SHA256(S||P)来对这些密码和Salt值进行计算了。如果计算结果能够与“P’”值相匹配,那么攻击也就成功了。在此次计算中所使用的“P”即为用户的真实密码。