Hash 函数

hash 函数就是将任意长度的一个字符串映射到一个固定长度字符串的过程,也叫摘要。

密码学中的 hash 函数可以用来构建安全的消息认证算法、签名算法和随机数生成算法。对于密码学 hash 算法,我们希望以下三个事情是很难做的:

  1. 修改一个消息却不改变哈希值;
  2. 对于一个给定的哈希值来构造一个消息;
  3. 找到两个具有相同哈希值的消息;

对于第一个性质,通常就是所谓的雪崩效应。哪怕仅仅修改了原消息的一个 bit,也会导致最后的哈希摘要产生巨大的变化。

第二个特性就是单向性。通过消息算出哈希非常容易,但是根据哈希找出原摘要十分的困难。

第三个特性就要求哈希函数耐碰撞。

常见的 Hash 函数包括 MD5、SHA-1、SHA-2 和 SHA-3。MD5 和 SHA-1 最常见,但是已经不是那么的安全了。推荐使用 SHA-2。

密码存储

通常业务是不会直接把密码存储到数据库中的。一旦数据库泄露,所有用户的密码就会泄露。通常都会把用户的密码进行 Hash 之后再存储到数据库中。校验用户密码的时候只要比对 Hash 值是否相同即可。

但是对于仅仅将密码进行 MD5 或者 SHA-1 的一次 Hash 之后存储也是不安全的。尽管攻击者不能根据哈希值算出原密码,但是攻击者可以构造一个叫做彩虹表的结构。彩虹表中存储了大量常用字符串和其 Hash 的映射关系。那么就可以根据 Hash 值反向查找到原密码了。

对于彩虹表,通常采用一种叫加盐的方式。对于用户的密码,进行 Hash 之前先将其和一个随机字符串结合之后再 Hash。如果盐使用不当的话,依然无法保证安全性。比如全局使用一个固定的盐,那么彩虹表只需要根据这个固定的盐再重新算一次就好了。盐一定要保证每个密码都是随机的。