手写一个加盐加密算法(java实现)

目录

前言

什么是MD5??

加盐算法

那别的人会不会跟你得到相同的UUID?

如何使用盐加密?

代码实现


前言

对于我们常见的登录的时候需要用到的组件,加密是一个必不可少的东西,如果我们往数据库存放用户的密码,是直接以明文存储的话,那么数据被窃取的时候,损失也就是最大的,因为别人可以很直观的看到你的用户数据,不需要任何破解成本。

所以我们需要对其加密。

目前最常见的两种数据加密方法:

  1. MD5加密
  2. 加盐算法

什么是MD5??

简单来说,md5就是讲遗传字符串通过某种特定的算法,来将其变化成另外一种形式,这样子就从明文的外观变成另外一个样子。但是由于背后的算法格式是固定的,所以每一个字符串都有固定的MD5格式。

有的用户为了方便记忆,把密码设置成简单的,有规律的字母或者数字组合,有的也喜欢使用单独一个单词这种,举一个简单的例子,例如密码1234567,和密码1726354,这两种密码,因为格式简单,很容易就被一次一次的试出来,也就是被暴力破解。

然后我们使用1234567进行MD5加密,但是这样就会让数据完全处于安全状态吗?

具体如何破解?也就是讲得到的,讲得到的密码进行MD5转换成为对应的哈希,然后于最初的哈希进行比对,要是匹配,那么这个密码就已经暴露给别人了

MD5底层存在一张彩虹表,几乎标记了所有字符串的MD5对照表。

有了彩虹表MD5就相当于是不存在了,因为一种字符串就只有一种特定的MD5格式

加盐算法

什么是盐?

其实盐就是一个随机值,没有任何规律,通过UUID.randomUUID()来生成一个唯一盐值。这个uuid是唯一的,具体唯一就是根据你的mac地址等内容生成的一个世界唯一的值,

那别的人会不会跟你得到相同的UUID?

下面的内容来自百度百科:

官方说明:产生错误的情况非常低,是故大可不必考虑这个重复的问题

如何使用盐加密?

这里存在一个合约公式,也就是:盐值(32位)+ $ + MD5加密后的密码

加密思路:用户输入一个明文密码,通过UUID得到一个盐值,这段密码首先使用MD5和盐值进行一个基本的加密,然后使用合约公式,将盐值和使用MD5+盐值生成的合约公式存入数据库

如何解密:这里的解密,不是指的直接将我们得到的合约公式又解密成明文,比如,用户想要登录,于是他输入了他之前设置的密码。这个密码被后端得到之后,就会进行验证,具体就是首先记住这个明文,然后通过数据库中存储的对应用户的合约公式拿出来,通过$来获取盐值,然后将用户输入的明文和拿到的盐值进行MD5加密,然后再合成一个:

盐值(32位)+ $ + MD5加密(盐值+用户输入的密码),

那么现在就有两个合约公式了,一个是用户注册时候生成的,一个是用户刚刚输入的,后台自动生成的合约公式

如果两个合约公式是一样的,那么就说明现在正在登录这个账户的人是这个账户的持有者,就可以允许访问

代码实现

在实现这个功能之前,你需要引入一个工具类,可以前往maven下载,地址为:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.14</version> <!--根据需要选择合适版本-->
</dependency>

代码案例:

java 复制代码
import org.apache.commons.codec.digest.DigestUtils;
 
public class Main {
   public static void main(String[] args) {
      String input = "Hello World"; // 输入字符串
      
      // 计算MD5值
      String md5Hash = DigestUtils.md5Hex(input);
      
      System.out.println("MD5 Hash: " + md5Hash);
   }
}

根据上面的案例进行加密:

java 复制代码
//  import org.apache.commons.codec.digest.DigestUtils;
//
//  import java.util.UUID;    
public static String encrypt(String password) {
        // 首先生产一个盐值
        // UUID.randomUUID() 会生成32位数字,然后+4位'-',我们不需要关注'-'在盐值的什么位置,我们只需要去除它
        String salt = UUID.randomUUID().toString();
        System.out.println(salt);
        // 去除'-'
        salt = salt.replaceAll("-","");
        // 然后使用盐值和传进来的密码进行md5加密
        String saltPassowrd = DigestUtils.md5Hex((salt+password).getBytes());

        // 然后和盐值进行拼接,然后返回
        String finalPassword = salt + '$' + saltPassowrd;
        return  finalPassword;
    }
}

解密:

解密的思路就是讲用户输入的密码重新进行一次加密,然后比对从数据库中拿到的是不是一样的:

java 复制代码
    public static boolean check(String inputPassword, String finalPassword){
        //首先判断这两个参数到底有没有值,并且判断数据库中拿到的finalPassword的length是否为65;
        if (inputPassword == null || inputPassword.isEmpty()) {
            // 这里先判断为不为空是因为后面的isEmpty的前提是字符串不为null,不然就会发生空指针异常
            return false;
        }
        if (finalPassword == null || finalPassword.isEmpty() || finalPassword.length() != 65) {
            return false;
        }
        // 从finalPassword中拿到盐值
        String salt = finalPassword.split("\\$")[0];
        String saltPassword = DigestUtils.md5Hex((salt+inputPassword).getBytes());
        String ret = salt + '$' + saltPassword;
        if (ret.equals(finalPassword)) {
            return true;
        }
        return false;
    }
相关推荐
zquwei几秒前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
TT哇7 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
火烧屁屁啦30 分钟前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
群联云防护小杜35 分钟前
如何给负载均衡平台做好安全防御
运维·服务器·网络·网络协议·安全·负载均衡
ihengshuai36 分钟前
HTTP协议及安全防范
网络协议·安全·http
w_312345443 分钟前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
岁岁岁平安1 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA1 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_19284999061 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
张国荣家的弟弟1 小时前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi