http://www.scotchmedia.com/tutorials/express/authentication/2/01
下面我列出了常用的密码存储手段,从不安全到安全:
- 明文存储
- hash 存储,例如 MD5,SHA,SHA256
- hash 加盐(salt)存储
1 密码必须散列存储
(内容略)
2 加Salt散列
加Salt可以一定程度上解决这一问题。所谓加Salt,就是加点“佐料”。其基本想法是这样的——当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。
这里的“佐料”被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过自己的密码和自己生成的散列值来找具有特定密码的用户,但这个几率太小了(密码和salt值都得和黑客使用的一样才行)。
下面详细介绍一下加Salt散列的过程。介绍之前先强调一点,前面说过,验证密码时要使用和最初散列密码时使用“相同的”佐料。所以Salt值是要存放在数据库里的。
图1. 用户注册
- 1)用户提供密码(以及其他用户信息);
- 3)系统将Salt值和用户密码连接到一起;
- 4)对连接后的值进行散列,得到Hash值;
- 5)将Hash值和Salt值分别放到数据库中。
图2. 用户登录
如图2所示,登录时,
- 1)用户提供用户名和密码;
- 2)系统通过用户名找到与之对应的Hash值和Salt值;
- 3)系统将Salt值和用户提供的密码连接到一起;
- 4)对连接后的值进行散列,得到Hash’(注意有个“撇”);
bcrypt是专门为密码存储而设计的算法,基于Blowfish加密算法变形而来,由Niels Provos和David Mazières发表于1999年的USENIX。
bcrypt最大的好处是有一个参数(work factor),可用于调整计算强度,而且work factor是包括在输出的摘要中的。随着攻击者计算能力的提高,使用者可以逐步增大work factor,而且不会影响已有用户的登陆。
bcrypt: 87.910ms
➜ db git:(master) ✗ node salt.js
(node:38203) DeprecationWarning: crypto.pbkdf2 without specifying a digest is deprecated. Please specify a digest
crypto的时间比bcrypt要好将近1倍。