生成一个随机数,我们称之为salt,
然后在数据库中记录salt和h=hash(pwd + salt),
查询的时候,得到用户的口令p,
后从数据库中查出salt,计算hash(p+salt),看是不是等于h,
等于就是对的,不等于就是不对的。
保护密码最好的的方式就是使用带盐的密码hash(salted password hashing).
只有加密hash函数(cryptographic hash functions)可以用来进行密码的hash。
这样的函数有SHA256, SHA512, RipeMD, WHIRLPOOL等。
根据一些经验得出来的规则就是盐的大小要跟hash函数的输出一致。比如,SHA256的输出是256bits(32bytes),盐的长度也应该是32个字节的随机数据。
一个使用加盐MD5的密码hash在实际使用中跟使用其他算法比如SHA256一样安全。不过如果可以的话,使用更安全的hash函数,比如SHA256, SHA512, RipeMD, WHIRLPOOL等是更好的选择。
盐要使用密码学上可靠安全的伪随机数生成器(Cryptographically Secure Pseudo-Random Number Generator (CSPRNG))来产生。
java.security.SecureRandom
每一个用户,每一个密码都要使用不同的盐。
用户每次创建账户或者修改密码都要使用一个新的随机盐。
永远不要重复使用盐。
盐的长度要足够,一个经验规则就是盐的至少要跟hash函数输出的长度一致。
盐应该跟hash一起存储在用户信息表里。
一个不错的学习web应用漏洞的资源是OWASP。除非你理解了OWASP Top Ten Vulnerability List,否则不要去写关系到敏感数据的程序。
经过充分测试的加密hash函数,比如SHA256, SHA512, RipeMD, WHIRLPOOL, SHA3等
不要使用 过时的hash函数,比如MD5,SHA1.任何自己设计的算法。
MD5 提供了最基本的安全 Hash 生成,使用时应为其添加 slat 来进一步加强它的安全性。
MD5 生成128位的 Hash。为了使它更安全,应该使用 SHA 算法生成 160-bit 或 512-bit 的长 Hash,其中 512-bit 是最强的。
虽然使用 SHA Hash 密码也能被当今快速的硬件破解,如要避免这一点,你需要的算法是能让暴力攻击尽可能的变慢且使影响减至最低。
这时候你可以使用 PBKDF2, BCrypt 或 SCrypt 算法。
PBKDF2(Password-Based Key Derivation Function)
美国政府机构已经将这个方法标准化,并且用于一些政府和军方的系统。 这个方案最大的优点是标准化,实现容易同时采用了久经考验的SHA算法。
DigestUtils.md5Hex(userName+DigestUtils.md5Hex(password))