当涉及到存储用户密码时,确保密码的安全非常重要。以往,我们通常都是采用 MD5 这种不可逆算法来进行密码数据的加密后存储,虽然MD5算法是一种常见的哈希函数,但是它已经不再被认为是安全的选项。
- 常规MD5加密,可使用彩虹表碰撞来进行攻击,可以匹配出原密码或者能得到相同密文的明文。
- 加盐使攻击者无法采用特定的查询表或彩虹表快速破解大量哈希值,但不能阻止字典攻击或暴力攻击。这里假设攻击者已经获取到用户数据库,意味着攻击者知道每个用户的盐值,根据Kerckhoffs’s principle,应该假设攻击者知道用户系统使用密码加密算法,如果攻击者使用高端GPU或定制的ASIC,每秒可以进行数十亿次哈希计算,针对每个用户进行字典查询的效率依旧很高效。
相较于MD5,推荐使用更安全的密码哈希函数,如BCrypt或Scrypt。这里我们来学习一下BCrypt来实现密码数据的加解密操作。
Bcrypt 是一个跨平台的文件加密工具。由它加密的文件可在所有支持的操作系统和处理器上进行转移。它的口令必须是8至56个字符,并将在内部被转化为448位的密钥。
Bcrypt是单向hash算法, 不可逆向解密,生成的密文是60位的。
- import org.mindrot.jbcrypt.BCrypt;
-
- public class PasswordUtils {
-
- // 生成哈希密码
- public static String hashPassword(String password) {
- String salt = BCrypt.gensalt(); // 生成随机盐值
- String hashedPassword = BCrypt.hashpw(password, salt); // 生成哈希密码
- return hashedPassword;
- }
-
- // 验证密码
- public static boolean checkPassword(String password, String hashedPassword) {
- return BCrypt.checkpw(password, hashedPassword);
- }
- }