博客系统中的加盐算法

目录

一、为什么要对密码进行加盐加密?

1、明文

[2、传统的 MD5](#2、传统的 MD5)

二、加盐加密

1、加盐算法实现思路

2、加盐算法解密思路

3、加盐算法代码实现

[三、使用 Spring Security 加盐](#三、使用 Spring Security 加盐)

[1、引入 Spring Security 框架](#1、引入 Spring Security 框架)

[2、排除 Spring Security 的自动加载](#2、排除 Spring Security 的自动加载)

[3、调用 Spring Security 的加盐](#3、调用 Spring Security 的加盐)


一、为什么要对密码进行加盐加密?

1、明文

明文是一定不行的,因为会很容易就会泄露用户的个人隐私

2、传统的 MD5

传统的 MD5 是有规律可循的,虽然 MD5 是不可逆的,但是是可以被暴力破解的

因为一个 字符串的 MD5 的值是固定的,当你有了一张 MD5 的穷举表(彩虹表)之后,这张表中记录了几乎所有字符串的 MD5 对照表,就可以对密码进行暴力破解

二、加盐加密

所以我们选择使用加盐加密对密码进行处理,而这种处理方法中的盐值是随机不固定的,随机也就意味着没有规律可言

在进行了加盐加密之后,同样是一串明文密码,在不同时间对其进行调用,结果都是不同的,这也是因为每次调用,都有一个随机的盐值

1、加盐算法实现思路

每次调用方法的时候,产生盐值(唯一的),然后使用这个盐值再加上我们的密码,最终得到了一个密码

2、加盐算法解密思路

首先需要两个密码:

1、需要验证的密码(用户输入的密码)

2、最终加密的密码(存在数据库中的密码)

核心思想:得到盐值

我们将盐值存放到最终密码的某一个位置

从密码中 拿到盐值之后,我们才能对原始用户输入的密码按照相同的路径进行加密,然后和最终的密码进行对比,从而判断用户输入的密码是否正确

验证密码伪代码:

已知:用户输入的明文密码,此用户在数据库中存储的最终密码(盐值 $ 加密后密码)

1、从最终密码中得到盐值

2、将用户输入的明文密码 + 盐值 进行加密操作 = 加密后的密码

3、使用 盐值 + 分隔符 + 加密后的密码 生成数据库存储的密码

4、对比生成的最终密码和数据库最终的密码是否相等

如果相等,那么用户名和密码就是对的,反之则是密码输入错误

3、加盐算法代码实现

java 复制代码
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));
    }*/
}

三、使用 Spring Security 加盐

1、引入 Spring Security 框架

XML 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

2、排除 Spring Security 的自动加载

java 复制代码
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

3、调用 Spring Security 的加盐

java 复制代码
 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));
相关推荐
vvw&13 分钟前
如何在 Ubuntu 22.04 上安装 Graylog 开源日志管理平台
linux·运维·服务器·ubuntu·开源·github·graylog
大哥_ZH17 分钟前
Linux umami在国产麒麟系统安装网站统计工具(只能上国内网站的系统)
linux·服务器
小池先生17 分钟前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
o(╥﹏╥)33 分钟前
在 Ubuntu 上安装 VS Code
linux·运维·vscode·ubuntu·vs
AI慧聚堂1 小时前
自动化 + 人工智能:投标行业的未来是什么样的?
运维·人工智能·自动化
不爱学英文的码字机器1 小时前
[Linux] Shell 命令及运行原理
linux·运维·服务器
cdut_suye1 小时前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
qq_433618441 小时前
shell 编程(三)
linux·运维·服务器
苹果醋31 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate