博客系统中的加盐算法

目录

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

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));
相关推荐
DC_BLOG23 分钟前
IPv6(四)
运维·服务器·网络·ip
shelby_loo23 分钟前
通过 Docker 部署 MySQL 服务器
服务器·mysql·docker
ZBzibing29 分钟前
[游戏技术]L4D服务器报错解决
服务器·游戏
沈艺强29 分钟前
伊犁linux 创建yum 源过程
linux·运维·服务器
拾光师32 分钟前
linux命令行快捷键
linux·运维·服务器
Dola_Pan2 小时前
Linux文件IO(二)-文件操作使用详解
java·linux·服务器
wang_book3 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
prcyang3 小时前
Docker Compose
运维·docker·容器
脚踏实地的大梦想家3 小时前
【Docker】安装全流程与配置完整镜像源(可安装 nginx)
运维·docker·容器
城南云小白4 小时前
Linux网络服务只iptables防火墙工具
linux·服务器·网络