目录
明文是一定不行的,因为会很容易就会泄露用户的个人隐私
传统的 MD5 是有规律可循的,虽然 MD5 是不可逆的,但是是可以被暴力破解的
因为一个 字符串的 MD5 的值是固定的,当你有了一张 MD5 的穷举表(彩虹表)之后,这张表中记录了几乎所有字符串的 MD5 对照表,就可以对密码进行暴力破解
所以我们选择使用加盐加密对密码进行处理,而这种处理方法中的盐值是随机不固定的,随机也就意味着没有规律可言
在进行了加盐加密之后,同样是一串明文密码,在不同时间对其进行调用,结果都是不同的,这也是因为每次调用,都有一个随机的盐值
每次调用方法的时候,产生盐值(唯一的),然后使用这个盐值再加上我们的密码,最终得到了一个密码
首先需要两个密码:
1、需要验证的密码(用户输入的密码)
2、最终加密的密码(存在数据库中的密码)
核心思想:得到盐值
我们将盐值存放到最终密码的某一个位置
从密码中 拿到盐值之后,我们才能对原始用户输入的密码按照相同的路径进行加密,然后和最终的密码进行对比,从而判断用户输入的密码是否正确
验证密码伪代码:
已知:用户输入的明文密码,此用户在数据库中存储的最终密码(盐值 $ 加密后密码)
1、从最终密码中得到盐值
2、将用户输入的明文密码 + 盐值 进行加密操作 = 加密后的密码
3、使用 盐值 + 分隔符 + 加密后的密码 生成数据库存储的密码
4、对比生成的最终密码和数据库最终的密码是否相等
如果相等,那么用户名和密码就是对的,反之则是密码输入错误
- public class PasswordUtils {
- /**
- * 1、 加盐并生成密码
- * @param password 明文密码
- * @return 保存到数据库中的密码
- */
- public static String encrypt(String password){
- // 产生盐值(32位)
- String salt = UUID.randomUUID().toString().replace("-","");
- // 生成加盐之后的密码
- String saltPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
- // 生成最终的密码 (保存到数据库中的密码)【约定格式: 32位盐值 + $ + 32位加盐后密码】
- String finalPassword = salt + "$" + saltPassword;
- return finalPassword;
- }
-
- /**
- * 2、生成加盐的密码(方法一的重载)
- * @param password 明文
- * @param salt 盐值
- * @return 数据库中的最终密码
- */
- public static String encrypt(String password,String salt) {
- // 生成加盐之后的密码
- String saltPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
- // 生成最终的密码
- String finalPassword = salt + "$" + saltPassword;
- return finalPassword;
- }
-
- /**
- * 3、验证密码
- * @param inputPassword 用户输入的明文密码
- * @param finalPassword 数据库中存储的最终密码
- * @return
- */
- public static boolean check(String inputPassword,String finalPassword){
- if (!StringUtils.hasLength(inputPassword) || !StringUtils.hasLength(finalPassword)
- || finalPassword.length() != 65){
- return false;
- }
- // 1、得到盐值
- String salt = finalPassword.split("\\$")[0];
- // 2、使用加密方式对明文和盐值进行加密
- String confirmPassword = encrypt(inputPassword,salt);
- // 进行对比
- return confirmPassword.equals(finalPassword);
-
- }
-
- /* public static void main(String[] args) {
- String password = "123456";
- String finalPassword = PasswordUtils.encrypt(password);
- System.out.println("加密:" + PasswordUtils.encrypt(password));
- String inputPassword = "12345";
- System.out.println("对比:" + inputPassword + "是否等于" + password + "结果" +
- PasswordUtils.check(inputPassword,finalPassword));
- String inputPassword2 = "123456";
- System.out.println("对比:" + inputPassword2 + "是否等于" + password + "结果" +
- PasswordUtils.check(inputPassword2,finalPassword));
- }*/
- }
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-securityartifactId>
- dependency>
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
- BCryPasswordEncoder passwordEncoder = new BCryPasswordEncoder();
- String password = "123456";
- String finalPassword = passwordEncoder.encode(password);
- System.out.println("第一次加密:" + finalPassword);
- System.out.println("第二次加密:" + passwordEncoder.encode(password));
- System.out.println("第三次加密:" + passwordEncoder.encode(password));
-
- // 验证
- String inpuPassword = "12345";
- System.out.println("错误密码比对结果:" + passwordEncoder.matches(inpuPassword,finalPassword));
- String inputPassword2 = "123456";
- System.out.println("错误密码比对结果:" + passwordEncoder.matches(inpuPassword2,finalPassword));