SpringBoot开发-数据加密

news2024/11/15 16:53:50

提示:本篇文章介绍各种加密工具以及数据脱密工具的使用

文章目录

  • 前言
  • 一、AES加密算法
  • 二、AES加密算法工具使用
    • (一)引入依赖
    • (二)编写工具类
    • (三)测试
  • 三、MD5加密算法
  • 四、MD5加密工具使用
    • (一)编写工具类
    • (二) 测试类
    • (三)测试
    • (四)MD5加随机盐
      • (1)MD5+盐工具类
      • (2)测试
  • 五、脱密处理
    • (一)正则表达式对数据做脱敏处理
    • (二)测试
  • 总结


前言

在开发过程中,考虑到数据安全性问题,我们经常会将一些敏感的数据进行加密,例如用户的密码,身份证,等信息进行加密,对用户手机号银行卡等信息进行脱敏处理,防止系统用户信息泄露。


一、AES加密算法

AES(英语全称:Advanced Encryption Standard,中文名称:高级加密标准)。是一种对称加密算法,广泛用于保护数据的安全性。它由美国国家标准技术局(NIST)于2001年采用,取代了以前的 DES(数据加密标准)。

对称加密算法:意味着加密和解密使用相同的密钥。

主要特点:
对称加密:加密和解密使用相同的密钥。
支持多种密钥长度:可使用 128、192 或 256 位密钥,长度越长,安全性越高。
块加密:以 128 位为块进行加密。
安全性高:目前被认为是非常安全,广泛应用于金融、政府和商业领域。

工作模式:
AES 可与多种工作模式结合使用,例如:
ECB(电子密码本):简单但不安全,容易受到攻击。
CBC(密码块链接):更安全,使用初始向量(IV)来增强安全性。
GCM(伽罗瓦计数模式):提供认证和加密,适用于网络通信。

应用场景:
数据库加密
文件加密
VPN 和 SSL/TLS 通信

AES 在线工具 https://tool.hiofd.com/aes-encrypt-online/

二、AES加密算法工具使用

(一)引入依赖

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.4</version>
</dependency>

(二)编写工具类

public class EncryptionUtil {

    private static final String SECRET_KEY = "MD_AES256";//秘钥自己设置
    
    public static String encrypt(String data) {
        AES256TextEncryptor encryptor = new AES256TextEncryptor();
        encryptor.setPassword(SECRET_KEY);
        return encryptor.encrypt(data);
    }
    public static String decrypt(String encryptedData) {
        AES256TextEncryptor encryptor = new AES256TextEncryptor();
        encryptor.setPassword(SECRET_KEY);
        return encryptor.decrypt(encryptedData);
    }
    
}

(三)测试

新增用户时,对用户输入密码进行加密

@PostMapping("/add")
public boolean add(@RequestBody User user){
     // 对用户密码加密
     String encryptedPassword = EncryptionUtil.encrypt(user.getPassword());
     user.setPassword(encryptedPassword);
     user.setCreateTime(LocalDateTime.now());
     user.setUpdateTime(LocalDateTime.now());
     return userService.save(user);
 }

查询用户时,查询密码是否解密成功(这里只是为了演示,实际开发中部展示用户密码的)

@GetMapping("/list")
public List<User> list(){
      List<User> userList = userService.list();
      //查看用户密码是否解密成功
      userList.stream().forEach(user ->
          user.setPassword(EncryptionUtil.decrypt(user.getPassword())));
      return userList;
  }

PostMan 添加一个用户
在这里插入图片描述
查看数据库中,用户密码保存后是否加密了
在这里插入图片描述
查询用户信息,查看解密后的密码
在这里插入图片描述
当我们再次加入一个用户,用户密码依然是 123456,我们查看加密效果
在这里插入图片描述
在这里插入图片描述

三、MD5加密算法

MD5(Message-Digest Algorithm 5)是一种广泛使用的加密哈希函数,它将任意长度的输入数据转换为固定长度的 128 位(16 字节)哈希值。其主要特点包括:

单向性:MD5 是单向函数,不能从哈希值逆向计算出原始输入。
固定输出:无论输入数据大小如何,MD5 始终生成相同长度的哈希值。
快速计算:MD5 可以迅速处理数据并生成哈希值。
碰撞性:理论上,两个不同的输入可以产生相同的哈希值,这种现象称为碰撞。由于 MD5 的安全性问题,已经不再推荐用于加密敏感数据。

四、MD5加密工具使用

(一)编写工具类

public class MD5Util {
    public static String encrypt(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();

            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

(二) 测试类

@PostMapping("/add")
public boolean add(@RequestBody User user){
    // 对用户密码加密(MD5加密)
    String encryptedPassword = MD5Util.encrypt(user.getPassword());
    user.setPassword(encryptedPassword);
    user.setCreateTime(LocalDateTime.now());
    user.setUpdateTime(LocalDateTime.now());
    return userService.save(user);
}

在这里插入图片描述
从结果上看,如果两个相同用户输入密码一致,那么他们加密后的结果是一致

(三)测试

测试使用MD5加密的两个用户密码是否为123456

@Test
public void testUserPassword(){
    User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, "王二麻子"));
    String password = user.getPassword();
    String testPassword = MD5Util.encrypt("123456");
    if(password.equals(testPassword)){
        System.out.println("密码正确");
    }else {
        System.out.println("密码错误");
    }
}

输出结果是:密码正确

(四)MD5加随机盐

从以上MD5加密我们可以看出,MD5加密如果用户输入密码相同,加密后的密文是相同,MD5可以通过穷举暴力破解,因此有了随机盐概念,将用户输入的密码+系统随机生成字符串一同加密,这样可以增加密文的安全性

(1)MD5+盐工具类

public class MD5Util {

    //生成随机盐
    public static byte[] generateSale(){
        SecureRandom secureRandom = new SecureRandom();
        byte[] salt = new byte[16];
        secureRandom.nextBytes(salt);
        return salt;
    }
    public static String encrypt(String password, byte[] salt) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(salt); // 加入盐
            md.update(password.getBytes()); // 加入密码
            byte[] hashedPassword = md.digest();
            return Base64.getEncoder().encodeToString(hashedPassword); // 以 Base64 格式返回哈希值
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

(2)测试

@PostMapping("/add")
public boolean add(@RequestBody User user){
    //生成随机盐
    byte[] salt = MD5Util.generateSale();
    user.setSalt(Base64.getEncoder().encodeToString(salt));
    // 对用户密码加密(MD5+随机盐)
    String encryptedPassword = MD5Util.encrypt(user.getPassword(),salt);
    user.setPassword(encryptedPassword);
    user.setCreateTime(LocalDateTime.now());
    user.setUpdateTime(LocalDateTime.now());
    return userService.save(user);
}
@PostMapping("/add")
public boolean add(@RequestBody User user){
    //生成随机盐
    byte[] salt = MD5Util.generateSale();
    user.setSalt(Base64.getEncoder().encodeToString(salt));
    // 对用户密码加密(MD5+随机盐)
    String encryptedPassword = MD5Util.encrypt(user.getPassword(),salt);
    user.setPassword(encryptedPassword);
    user.setCreateTime(LocalDateTime.now());
    user.setUpdateTime(LocalDateTime.now());
    return userService.save(user);
}

在这里插入图片描述
之后比较用户密码很简单,将随机盐从数据库中查询出来加上用户输入的密码一起加密与数据库用户密码进行比较即可

@Test
public void testUserPassword(){
    User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, "虞姬"));
    byte[] salt = Base64.getDecoder().decode(user.getSalt());
    String password = user.getPassword();
    String testPassword = MD5Util.encrypt("123456",salt);
    if(password.equals(testPassword)){
        System.out.println("密码正确");
    }else {
        System.out.println("密码错误");
    }
}

五、脱密处理

除了对数据的加密外,我们还可以对数据展示做一些脱敏处理

(一)正则表达式对数据做脱敏处理

public class DesensitizationUtil {

    // 对手机号进行脱敏
    public static String maskPhoneNumber(String phoneNumber){
        return phoneNumber.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2");
    }

    // 对身份证进行脱敏
    public static String maskIdCard(String idCard){
        return idCard.replaceAll("(\\d{4})\\d{10}(\\w{4})","$1**********$2");
    }

    // 对银行卡号进行脱敏
    public static String maskBankCard(String bankCard){
        return bankCard.replaceAll("(\\d{4})\\d{10}(\\d{4})","$1**********$2");
    }
}

(二)测试

@GetMapping("/list")
 public List<User> list(){
     List<User> userList = userService.list();
     //查看用户密码是否解密成功
     userList.forEach(user -> {
         user.setPassword(EncryptionUtil.decrypt(user.getPassword()));
         user.setPhoneNum(DesensitizationUtil.maskPhoneNumber(user.getPhoneNum()));
         user.setIdCard(DesensitizationUtil.maskIdCard(user.getIdCard()));
     });
     return userList;
 }

在这里插入图片描述


总结

以上就是基本加密方法使用,如果想要项目使用多种加密方式,可以导入Hutool工具包,Hutool工具包包含了以上的加密工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2151211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows【环境 01】服务器系统重装后的服务恢复(ES\Redis\Jafka\Tomcat)环境变量和服务注册

服务器系统重装后的服务恢复 1.原因2.问题处理2.1 JDK2.2 Elasticsearch2.3 Redis2.4 Jafka2.5 Tomcat 3.总结 1.原因 Windows 服务器系统盘损坏&#xff0c;换了硬盘并重做了系统&#xff0c;其他磁盘未损坏但安装的服务无法正常运行了&#xff0c;包括&#xff1a; Elastic…

莱卡相机sd内存卡格式化了怎么恢复数据

在数字化时代&#xff0c;相机已成为我们记录生活、捕捉瞬间的重要设备。而SD内存卡&#xff0c;作为相机的存储媒介&#xff0c;承载着我们的珍贵记忆和重要数据。然而&#xff0c;有时由于误操作、系统错误或其他原因&#xff0c;我们可能会不小心格式化SD内存卡&#xff0c;…

Windows11自带截图工具的录屏功能

WinShiftS打开截图工具。 点击工具栏上的“录屏”按钮&#xff0c;或者按下WinAltR组合键。启动录屏模式&#xff0c;并允许你开始录制屏幕内容。 可以选择录制整个屏幕还是只录制一个特定的窗口。此外&#xff0c;还可以设置录制视频的分辨率和帧率。如果希望录制屏幕上的音…

在 deepin 上除了 Steam,还能怎么玩游戏?

查看原文 前段时间&#xff0c;很多朋友在 deepin 23 上实现了《黑神话&#xff1a;悟空》的通关&#xff0c;那么除了通过 Steam 玩 Windows 游戏之外&#xff0c;还有其他可以使用的游戏平台吗&#xff1f; 回答&#xff0c;当然是可以哒&#xff01; 游戏平台介绍 今天介…

每日OJ题_牛客_WY22 Fibonacci数列(斐波那契)

目录 牛客_WY22 Fibonacci数列&#xff08;斐波那契&#xff09; 解析代码 牛客_WY22 Fibonacci数列&#xff08;斐波那契&#xff09; Fibonacci数列_牛客题霸_牛客网 解析代码 求斐波那契数列的过程中&#xff0c;判断⼀下&#xff1a;何时 n 会在两个 fib 数之间。 #in…

拥塞控制算法的 rtt 公平性

我强调过&#xff0c;拥塞控制的核心在公平可用性&#xff0c;公平性由 buffer 动力学保证&#xff0c;而 buffer 动力学有两种表现形式&#xff1a; buffer 占比决定带宽占比&#xff0c;以 aimd 为例&#xff1b;带宽越小&#xff0c;buffer 挤兑加速比越大&#xff0c;以 b…

HTTP中的event-stream,eventsource,SSE,chatgpt,stream request,golang

我们都知道chatgpt是生成式的&#xff0c;因此它返回给客户端的消息也是一段一段的&#xff0c;所以普通的HTTP协议无法满足&#xff0c;当然websocket是能满足的&#xff0c;但是这个是双向的通信&#xff0c;其实 SSE&#xff08;Server-Sent Events&#xff09; 正好满足这个…

树与图的深度优先遍历(dfs的图论中的应用)

模板题 846. 树的重心 给定一颗树&#xff0c;树中包含 nn 个结点&#xff08;编号 1∼n&#xff09;和 n−1条无向边。 请你找到树的重心&#xff0c;并输出将重心删除后&#xff0c;剩余各个连通块中点数的最大值。 重心定义&#xff1a;重心是指树中的一个结点&#xff…

RabbitMQ 高级特性——发送方确认

文章目录 前言发送方确认confirm 确认模式return 退回模式 常见面试题 前言 前面我们学习了 RabbitMQ 中交换机、队列和消息的持久化&#xff0c;这样能够保证存储在 RabbitMQ Broker 中的交换机和队列中的消息实现持久化&#xff0c;就算 RabbitMQ 服务发生了重启或者是宕机&…

【Android】浅析MVC与MVP

【Android】浅析MVC与MVP 什么是架构&#xff1f; 架构&#xff08;Architecture&#xff09;在软件开发中指的是软件系统的整体设计和结构&#xff0c;它描述了系统的高层组织方式&#xff0c;包括系统中各个组件之间的关系、依赖、交互方式&#xff0c;以及这些组件如何协同…

基于OpenCV的YOLOv5图片检测

利用OpenCV的DNN模块加载onnx模型文件进行图片检测。 1、使用的yolov5工程代码&#xff0c;调用export.py导出onnx模型。 2、下载opencv版本&#xff0c;https://opencv.org/releases/ 使用opencv版本4.5.3或以上&#xff0c;本文使用的opencv4.6.0 3、使用vc20…

4.使用 VSCode 过程中的英语积累 - View 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…

STM32 使用 CubeMX 实现按键外部中断

目录 问题背景知识参考需要改什么注意尽量不要在中断函数使用 循环函数做延时中断函数中延时方法调试 问题 我想实现按钮触发紧急停止类似功能&#xff0c;需要使用按键中断功能。 背景知识 GPIO 点亮 LED。stm32cubemx hal学习记录&#xff1a;GPIO输入输出。STM32—HAL库 …

【实战篇】MySQL是怎么保证高可用的?

背景 在一个主备关系中&#xff0c;每个备库接收主库的 binlog 并执行。正常情况下&#xff0c;只要主库执行更新生成的所有 binlog&#xff0c;都可以传到备库并被正确地执行&#xff0c;备库就能达到跟主库一致的状态&#xff0c;这就是最终一致性。 但是&#xff0c;MySQL…

免费在线压缩pdf 压缩pdf在线免费 推荐简单好用

压缩pdf在线免费&#xff1f;在日常生活和工作学习中&#xff0c;处理PDF文件是常见任务。但有时PDF文件体积较大&#xff0c;给传输、存储和分享带来不便。因此&#xff0c;学习PDF文件压缩技巧十分必要。压缩PDF文件是指通过技术手段减小文件占用的存储空间&#xff0c;同时尽…

[Redis][Hash]详细讲解

目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…

CSS - 通用左边图片,右边内容,并且控制长度溢出处理模板(vue | uniapp | 微信小程序)

前言 通用模板&#xff0c;可适用于任意前端项目。 如下图所示&#xff0c;手机电脑通用。 示例代码 根据自己的需求修改即可。 <body><div class"container"><!-- 头像图片 --><img class"avatar" src"https://cdn.uviewui.com…

C++初阶学习——探索STL奥秘——标准库中的priority_queue与模拟实现

1.priority_queque的介绍 1.priority_queue中文叫优先级队列。优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于堆&#xff0c;在堆中可以随时插入元素&#xff0c;并且只能检索最大堆元…

学习大数据DAY59 全量抽取和增量抽取实战

目录 需求流程&#xff1a; 需求分析与规范 作业 作业2 需求流程&#xff1a; 全量抽取 增量抽取 - DataX Kettle Sqoop ... 场景: 业务部门同事或者甲方的工作人员给我们的部门经理和你提出了新的需 求 流程: 联系 > 开会讨论 > 确认需求 > 落地 需求文档( 具体…

Vue 项目中引入 Axios 详解

Vue 项目中引入 Axios 详解 在 Vue 项目中&#xff0c;axios 是一个非常流行的 HTTP 客户端&#xff0c;用于向服务器发送请求并处理响应。本文将详细说明如何在 Vue 项目中引入 Axios 插件&#xff0c;以及如何进行基本的配置&#xff0c;包括构建、配置域名、设置全局错误拦…