简介
本文用示例介绍使用对密码进行加密的算法:bcrypt。
bcrypt是一种自带盐值(自动加盐)的加密方案。
bcrypt加密原理
加密过程
- 先随机生成salt
- salt跟password进行hash
注意
- 对于同一个密码,每次生成的hash是不同的
- hash中包含了salt
校验过程
- 从hash中取出salt
- salt跟password进行hash计算
- 将得到的hash跟数据库中提取的的hash进行比对返回Boolean类型:true/false
bcrypt与md5的区别
项 | md5 | bcrypt |
密文长度 | 32位 | 60位 |
安全性 | 安全性差。 密码相同时,加密后密文一样。 提升安全性的方案:加密前生成随机的盐值(字符串),将它与密码拼接,然后再使用md5加密。 | 安全性好。 密码相同时,生成的密文是不一样的。(因为它自动生成随机盐值) |
加密耗时 | 短 | 略长 |
示例
1、引入依赖
pom.xml加入如下依赖:
<dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.4</version> </dependency>
总的pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo_SpringBoot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo_SpringBoot</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.0.RELEASE</version> </plugin> </plugins> </build> </project>
2、写测试类
package com.example.controller; import org.mindrot.jbcrypt.BCrypt; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/test") public String test() { String password = "123456"; // 加密 String encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt()); System.out.println(encodedPassword); // 使用正确密码验证密码是否正确 boolean flag = BCrypt.checkpw(password, encodedPassword); System.out.println(flag); // 使用错误密码验证密码是否正确 flag = BCrypt.checkpw("111222", encodedPassword); System.out.println(flag); System.out.println("-------------------------------------------"); return "test success"; } }
3、测试
访问:http://localhost:8080/test/
多次访问后的后端结果:
$2a$10$63I66GOCxncIufBHEzcbF.LUBA45jCFwATVXz7MTzp7bpDn.SQMSG true false ------------------------------------------- $2a$10$CV7iT/TpZVx23IdEvMHhleRSnIPPI2N/s..Cl9Bd50V2LFdff1woa true false ------------------------------------------- $2a$10$wNTnhUedcx0InkAflqWm0O9M163WRR/RCGLdBSfhrgzJQuBZoEeEG true false -------------------------------------------
密文含义
示例密文:
$2a$10$CV7iT/TpZVx23IdEvMHhleRSnIPPI2N/s..Cl9Bd50V2LFdff1woa
- $:分割符,无意义;
- 2a:bcrypt加密版本号;
- 10:cost的值(默认值);
- 之后的22位:salt值;
- 之后:密码的密文
请先
!