Bcrypt 是一个很流行的密码哈希算法,是 Niels Provos 和 DavidMazières 基于 Blowfish 加密算法设计的密码哈希算法,于 1999 年在 USENIX 协会上提交。Bcrypt 在设计上包含了一个盐 Salt 来防御彩虹表攻击,还提供了一种自适应功能,可以随着时间的推移,通过增加迭代计数以使其执行更慢,使得即便在增加计算能力的情况下,Bcrypt 仍然能保持抵抗暴力攻击。
Bcrypt 是 OpenBSD 和 SUSE Linux 等操作系统默认的密码哈希算法。但是在使用 Bcrypt 算法的实现时,要注意它有最大密码长度限制,通常为 50~72 字符,准确的长度限制取决于具体的 Bcrypt 实现。超过最大长度的密码将被截断。
下面使用 Spring Security 的 BCryptPasswordEncoder 为例:
- BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
- // 72 字符
- String password1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- // 73 字符
- String password2 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
- String encodedPassword1 = passwordEncoder.encode(password1);
- boolean matches = passwordEncoder.matches(password2, encodedPassword1);
- System.out.println("encodedPassword1: " + encodedPassword1);
- System.out.println("matches: " + matches);
当运行程序时,会输出这样的结果:
- encodedPassword1: $2a$10$A5OpVKgjEZzmy6UNsqzkjuG2xGET1wp3b/9ET5dz/tHQ3eRvyXSSO
- matches: true
这证明了 Password 字符串超过 72 字符的部分被截断丢弃了。
要解决 Bcrypt 密码算法 72 字符长度限制的问题,可以这样:
先使用 SHA-256 算法对字符串进行加密,再使用 Bcrypt 算法加密,用伪码示意如下:
- hashpw(sha256('password'), salt);
来源: http://blog.csdn.net/chszs/article/details/60970765