1 密码哈希
  哈希算法任何数量的数据转换为无法反转的固定长度的“指纹”。即使原始输入的数据变化很小,但是其输出的结果相差很大。

(“hello”)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98

(“hallo”)= 8756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238ff3f9e94bc3

  使用哈希之后,如何校验用户的用户名密码呢?
    用户创建一个帐户时。输入的密码被散列并存储在数据库中。

    当用户登录时,对其输入的密码散列,对照其实际密码(从数据库检索)。

    如果哈希匹配,则授予用户访问权限。如果不是,则告诉用户他们输入了无效的登录凭

    常用的较为安全的密码哈希算法:SHA256,SHA512,等。

2 破解密码

  因为哈希算法,相同的输入时,会有一个相同的输出值。由此就出现了几种破解方法:

2.1字典和蛮力攻击

  这是最简单的密码猜解方法,对每个值进行哈希,然后与数据库泄露出的密码哈希值进行对比,如果相同,代表着密码被猜解。

  字典攻击:使用的字典一般含单词,词组,常用密码以及其他可能用作密码的字符串。

  蛮力攻击: 尝试所有可能的字符组合。

  虽然如果密码长度够长、复杂度较高,会给破解带来一些难度,但是没有办法完全阻止。

2.2 查找表

查找表的思路是字典中,首先预置好哈希值。然后将实际密码的哈希值与之搜索对比。这是一种非常有效的方法,可以非常快速地破解许多相同类型的哈希。

  2.3 反向查找表

  这种攻击特别有效,因为许多用户通常使用相同的密码。所以可以对某个字符进行哈希,然后去数据库中进行查询此哈希值映射的用户名。

  例如:

  在用户的哈希列表中搜索哈希(password1)...:匹配[小明,小花,小白]

  在用户的哈希列表中搜索哈希(password2)...:匹配[李明]

 

3 加盐值

  首先可以通过一个场景了解盐值的作用:

为password=123456。

即最终存储的密码为:PASSWORD=123456+salt

 

  由于密码是由用户设定的,在实际应用中,用户设置的密码复杂度可能不够高,同时不同的用户极有可能会使用相同的密码,那么这些用户对应的密文也会相同,这样,当存储用户密码的数据库泄露后,攻击者会很容易便能找到相同密码的用户,从而也降低了破解密码的难度,因此,在对用户密码进行加密时,需要考虑对密码进行掩饰,即使是相同的密码,也应该要保存为不同的密文,即使用户输入的是弱密码,也需要考虑进行增强,从而增加密码被攻破的难度,而使用带盐的加密hash值便能满足该需求。

  3.1  加密存储

  输入: 密码字符串passWord

  输出:盐值 salt 、密码密文passWordHash

  可以将salt放到passWord前面作为前缀或放到passWord后面作为后缀得到新的字符串PS,即,PS = password和salt的组合串;

密码密文passWordHash = Hash加密函数(PS );

3.2 密码校验

  输入: 密码字符串passWord

  输出:密码校验是否成功

  处理:

、取出当前用户密码加密时使用的盐值salt

、得到本次输入的密码passWordCur和盐值salt的组合字符串PS

、得出本次输入密码的密文passWordHashCur= Hash加密函数(PS );

、比较passWordHashCur和用户最初设置的密码密文passWordHash是否一致,如果一致,则校验成功,否则校验失败。


3.4 盐值的产生与存储

  盐值应该使用安全随机数生成;不能写死在代码中或者配置文件中、数据库中。而且对盐值的长度也应该有一定的要求,较短的盐值,仍然有被破解的风险。