Storing User Passwords Securely: hashing, salting, and Bcrypt
在存储密码的数据库被攻破的前提下,破解密码的成本越高则密码的安全性就越高。 一般来说,密码在存储到数据库前都经过hash加密。 需要考虑hash函数的性能对密码安全性的影响。 比如对于SHA256来说,当前的普通计算机能在一秒内计算数百万的hash值,定制的计算机则可以提供每秒数十亿次的hash运算。 在这种情况下,很多密码安全的设计都变得不再安全。
首先,最不安全的方式是明文存储密码。 其次,对密码明文进行sha1加密、对密码明文进行sha1加密时加上固定的salt值、为每个用户分配不同的salt值都是不安全的。
推荐使用bcrypt加密密码。
bcrypt相比sha1等来说更慢,这意味着破解密码的cpu成本更高。
比如log_rounds
值设为10时,大概需要100毫秒来计算hash值。
还可以通过增加log_rounds
值来抵消未来计算机运算能力的提高。
一些bcrypt实现还原生支持per-user-salt。
Dropbox也主要采用了per-user-salt加bcrypt来存储用户密码。 Dropbox在用bcrypt hash之前,会先用SHA512对密码做预处理——把密码hash成512 bit的定长字符串。 预处理有两个作用:一是对于很短的密码,提高它的entropy(熵);二是防止输入密码过长造成潜在的DoS attacks风险(bcrypt很“慢”)。 Dropbox还引入了global pepper(既有“盐”又有“胡椒粉”)——对bcrypt的hash值再用AES256做进一步的加密。 pepper存储在数据库之外的地方。AES256是对称加密,方便未来更新pepper值。