加盐密码
Jun 9, 2016
密文存储
数据库中用户的密码一般是密文存储的,作用 ?
- 防止被脱裤后账号泄露
- 防止内部DBA或者有权限人员直接可以看到用户账号密码
加密hash算法
传统的md5加密,在彩虹表的攻势下已经不再安全,新的加密方法呢?
可以使用
- OpenWall的Portable PHP password hashing framework
- 经过充分测试的加密hash函数,比如SHA256, SHA512, RipeMD, WHIRLPOOL, SHA3等
- 设计良好的key扩展hash算法,比如PBKDF2,bcrypt,scrypt
- crypt的安全版本。($2y$, $5$, $6$)
不要使用
- 过时的hash函数,比如MD5,SHA1
- crypt的不安全版本。($1$, $2$, $2x$, $3$)
- 任何自己设计的算法。
只依靠hash隐患
优秀的hash算法加密可以保障密文的安全,但如果多个企业只用一套”安全的加密算法”会有什么隐患?
- 网站A被脱裤,密文保障了密码的安全,但脱裤者自己注册一个号,得到了密文, 就可以得到一个明文->密文的映射,相当于破解了一个密文, 然后在数据中进行
select pwd="xxx"
操作,就可以得到相同密码的用户。 - 在密码爆炸的时代,用户在多个网站下的密码很可能是一样的,参考扎克伯克fb twitter linkedin 密码设置一样,被黑客破解的事件。
这样的话, 一个网站被脱裤,所以网站都有了危机。
显然,除了优秀的hash算法加密外,可以对它进行一点改进或者说增强, 一种方法就是 加盐。
盐(salt) 是开发设计者设计的一种随机字符串,在密文中加上盐的干扰,可以加大破解难度,变相提高安全性。
md5(md5(pwd) + salt) , 但md5已经不再安全。
改良下, SHA512( SHA512(pwd) + salt )
但暴力破解也是一个问题,利用一种慢哈希算法,设置一次加密的时间,执行一次hash加密会很慢,提高暴力破解的时间,变相提高安全性。
bcrypt(SHA512(pwd), salt, cost)
存储与验证过程
存储一个密码:
- 使用CSPRNG生成一个长的随机盐。
- 将密码和盐拼接在一起,使用标准的加密hash函数比如SHA256进行hash
- 将盐和hash记录在用户数据库中
验证一个密码:
- 从数据库中取出用户的盐和hash
- 将用户输入的密码和盐按相同方式拼接在一起,使用相同的hash函数进行hash
- 比较计算出的hash跟存储的hash是否相同。如果相同则密码正确。反之则密码错误。
资料: (http://drops.wooyun.org/papers/1066) (http://blog.coderzh.com/2016/01/10/a-password-security-design-example/)