密码加密说明
| 算法 | 安全性 | 密码专用 | 抗GPU攻击 | 抗ASIC攻击 | 加密结果是否为固定值 | 推荐程度 |
|---|---|---|---|---|---|---|
| MD5 | 禁止使用 | |||||
| SHA-1 | 禁止使用 | |||||
| SHA-256 | 不用于密码 | |||||
| bcrypt | 推荐 |
核心说明:
- 固定值 (
是):MD5、SHA-1、SHA-256 是传统的(加密)哈希函数,其设计是确定性的。对于相同的输入,无论何时何地计算,其输出(哈希值)永远相同。 - 非固定值 (
否):bcrypt 是密码哈希函数。其核心安全机制之一就是内置随机盐。即使对完全相同的密码,每次调用
bcrypt 也会生成一个完全不同的随机盐,并最终产生一个截然不同的哈希值。这是它与传统哈希函数的本质区别,也是它更安全、专为密码存储而设计的关键特征。
org.mindrot:jbcrypt 使用示例
pom.xml<dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.4</version> </dependency>Javapackage cn.com.xuxiaowei; import org.mindrot.jbcrypt.BCrypt; public class BCryptTests { public static void main(String[] args) { // 原始密码 String password = "xuxiaowei"; // 密码复杂度,默认:10 // 可使用 BCrypt.gensalt(int) 指定密码复杂度。数字越大,速度越慢 String gensalt = BCrypt.gensalt(); // 密码加密 String hashpw = BCrypt.hashpw(password, gensalt); // 示例:$2a$10$.Qhiq0ZLbPJPaRv2ezz1i.iFFNKp/A/c.Ou8iQv44GwpnC4PhIuei System.out.println(hashpw); // 密码对比 boolean checkpw = BCrypt.checkpw(password, hashpw); System.out.println(checkpw); } }
org.springframework.security:spring-security-crypto 使用示例
pom.xml<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.7.11</version> </dependency>Java- 最简单实用方式
package cn.com.xuxiaowei; import org.springframework.security.crypto.bcrypt.BCrypt; public class BCryptTests { public static void main(String[] args) { // 原始密码 String password = "xuxiaowei"; // 密码复杂度,默认:10 // 可使用 BCrypt.gensalt(int) 指定密码复杂度。数字越大,速度越慢 String gensalt = BCrypt.gensalt(); // 密码加密 String hashpw = BCrypt.hashpw(password, gensalt); // 示例:$2a$10$.Qhiq0ZLbPJPaRv2ezz1i.iFFNKp/A/c.Ou8iQv44GwpnC4PhIuei System.out.println(hashpw); // 密码对比 boolean checkpw = BCrypt.checkpw(password, hashpw); System.out.println(checkpw); } } - 使用
PasswordEncoder接口package cn.com.xuxiaowei; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; public class BCryptTests { public static void main(String[] args) { // 原始密码 String password = "xuxiaowei"; // 密码复杂度,默认:10 // 可使用 new BCryptPasswordEncoder(int) 指定密码复杂度。数字越大,速度越慢 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 密码加密 String encode = passwordEncoder.encode(password); // 示例:$2a$10$.Qhiq0ZLbPJPaRv2ezz1i.iFFNKp/A/c.Ou8iQv44GwpnC4PhIuei System.out.println(encode); // 密码对比 boolean matches = passwordEncoder.matches(password, encode); System.out.println(matches); } } - Spring Security 默认使用方式,密码对比时兼容多种加密方式,支持密码加密方式升级
PasswordEncoder#upgradeEncoding(String)- 密码加密后,存在前缀:
{bcrypt},代表密码加密方式
package cn.com.xuxiaowei; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; public class BCryptTests { public static void main(String[] args) { // 原始密码 String password = "xuxiaowei"; // 密码复杂度:10 PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); // 密码加密 String encode = passwordEncoder.encode(password); // 示例:{bcrypt}$2a$10$lNSOa/wFzp4jyyzalS4MGudghjJvHxy46GNPkl2Ce9UbSE66pScLy System.out.println(encode); // 密码对比 boolean matches = passwordEncoder.matches(password, encode); System.out.println(matches); } } - 密码加密后,存在前缀:
- 最简单实用方式