博客系统中的加盐算法

目录

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

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));
相关推荐
magic 2459 分钟前
第五章:Linux用户管理
linux·运维·服务器
小叶子来了啊15 分钟前
信息系统运行管理员:临阵磨枪版
运维·服务器·数据库
-天涯7623 分钟前
5.13/14 linux安装centos及一些操作命令随记
linux·运维·服务器
佩奇的技术笔记1 小时前
CentOS系统中升级Python 3.12.2版本
linux·运维·服务器
HackerKevn1 小时前
【项目】自主实现HTTP服务器:从Socket到CGI全流程解析
服务器·网络协议·http
北漂老男孩1 小时前
主流数据库运维故障排查卡片式速查表与视觉图谱
运维·数据库
源码云商1 小时前
基于SpringBoot的校园周边美食探索及分享平台【附源码+数据库+文档下载】
数据库·spring boot·美食
等等5431 小时前
Java EE初阶——线程安全
java·java-ee
薯条不要番茄酱1 小时前
【SpringBoot】从零开始全面解析SpringMVC (二)
java·spring boot·后端
小林学习编程1 小时前
Springboot考研信息平台
spring boot·后端·考研