Spring Boot 使用Jasypt加密

一、配置Jasypt

1.在pom.xml中导入依赖

        <!-- Jasypt 加密工具 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version></dependency>

注释:项目使用了@SpringBootApplication@EnableAutoConfiguration注解,可以直接使用starter依赖,否则要用其他方法。其他方法见参考文章里。

2.配置Jasypt信息

2.1 使用@Configuration配置信息

package com.xj.util.jasypt;import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*** @Author: xjfu* @Create: 2025/07/16 15:13* @Description: Jastpt配置信息*/@Configuration
public class JasyptConfig {@Value("${jasypt.encryptor.password:default-secret-key}")private String password;/*** 配置Jasypt加密器** @return StringEncryptor加密器实例*/@Bean("jasyptStringEncryptor")public StringEncryptor stringEncryptor() {PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();SimpleStringPBEConfig config = new SimpleStringPBEConfig();// 设置加密密钥 通过配置阐述,安全config.setPassword(password);//设置加密秘钥 直接写死,但是不安全//config.setPassword("xj20250716");// 设置加密算法// 注意:Jasypt 3.0.0之后默认算法为PBEWITHHMACSHA512ANDAES_256// 需要JDK 9+或添加JCE支持,否则可能报错// 如果使用较低版本的JDK,可以选择兼容的算法如PBEWithMD5AndDESconfig.setAlgorithm("PBEWithMD5AndDES");// 设置密钥获取迭代次数config.setKeyObtentionIterations("1000");// 设置加密器的池大小config.setPoolSize("1");// 设置随机盐生成器config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");// 设置字符串输出格式config.setStringOutputType("base64");encryptor.setConfig(config);return encryptor;}
}

2.2 使用配置文件方式

# Jasypt配置(必须放在最前面)
jasypt:encryptor:bean: jasyptStringEncryptor# 可以使用环境变量或命令行参数传入密钥password: ${JASYPT_ENCRYPTOR_PASSWORD:default-secret-key}algorithm: PBEWithMD5AndDESiv-generator-classname: org.jasypt.iv.RandomIvGenerator

2.3 配置文件详解

3.Jasypt工具类

package com.xj.util.jasypt;import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/*** @Author: xjfu* @Create: 2025/07/16 15:15* @Description: Jasypt工具类*/
@Component
public class JasyptUtil {private final StringEncryptor encryptor;@Autowiredpublic JasyptUtil(@Qualifier("jasyptStringEncryptor") StringEncryptor encryptor) {this.encryptor = encryptor;}/*** 加密方法** @param value 待加密的字符串* @return 加密后的字符串*/public String encrypt(String value) {return encryptor.encrypt(value);}/*** 解密方法** @param value 待解密的字符串* @return 解密后的字符串*/public String decrypt(String value) {return encryptor.decrypt(value);}
}

4.配置Jasypt的秘钥

4.1 IDEA中配置

4.1.1 配置方法一

--jasypt.encryptor.password=xj20250716

4.1.2 配置方法二

-Djasypt.encryptor.password=xj20250716

4.2 程序启动时命令行中带入

方式一:作为程序启动时的命令行参数来带入
java -jar app.jar --jasypt.encryptor.password=xxxxxx
 
方式二:作为程序启动时的应用环境变量来带入
java -Djasypt.encryptor.password=xxxxxx -jar app.jar

5.使用ENC()包裹加密密文

Jasypt使用特定格式来标识加密的属性值。在配置文件中,加密的值需要使用ENC(加密后的值)格式。

二、项目举例

1.项目架构

2.代码实现

MainApplication.java:

package com.xj.main;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;/*** @Author : xjfu* @Date : 2022/6/8 8:38* @Description :Spring Boot 启动类*/
@ComponentScan("com.xj")
@SpringBootApplication
@MapperScan("com.xj.dao.mapper")
public class MainApplication {public static void main(String[] args) {try{SpringApplication.run(MainApplication.class, args);}catch (Exception e){e.printStackTrace();}}
}

JasyptConfig.java:

package com.xj.util.jasypt;import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*** @Author: xjfu* @Create: 2025/07/16 15:13* @Description: Jastpt配置信息*/@Configuration
public class JasyptConfig {@Value("${jasypt.encryptor.password:default-secret-key}")private String password;/*** 配置Jasypt加密器** @return StringEncryptor加密器实例*/@Bean("jasyptStringEncryptor")public StringEncryptor stringEncryptor() {PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();SimpleStringPBEConfig config = new SimpleStringPBEConfig();// 设置加密密钥 通过配置阐述,安全config.setPassword(password);//设置加密秘钥 直接写死,但是不安全//config.setPassword("xj20250716");// 设置加密算法// 注意:Jasypt 3.0.0之后默认算法为PBEWITHHMACSHA512ANDAES_256// 需要JDK 9+或添加JCE支持,否则可能报错// 如果使用较低版本的JDK,可以选择兼容的算法如PBEWithMD5AndDESconfig.setAlgorithm("PBEWithMD5AndDES");// 设置密钥获取迭代次数config.setKeyObtentionIterations("1000");// 设置加密器的池大小config.setPoolSize("1");// 设置随机盐生成器config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");// 设置字符串输出格式config.setStringOutputType("base64");encryptor.setConfig(config);return encryptor;}
}

JasyptUtil.java:

package com.xj.util.jasypt;import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/*** @Author: xjfu* @Create: 2025/07/16 15:15* @Description: Jasypt工具类*/
@Component
public class JasyptUtil {private final StringEncryptor encryptor;@Autowiredpublic JasyptUtil(@Qualifier("jasyptStringEncryptor") StringEncryptor encryptor) {this.encryptor = encryptor;}/*** 加密方法** @param value 待加密的字符串* @return 加密后的字符串*/public String encrypt(String value) {return encryptor.encrypt(value);}/*** 解密方法** @param value 待解密的字符串* @return 解密后的字符串*/public String decrypt(String value) {return encryptor.decrypt(value);}
}

JasyptController.java:

package com.xj.controller;import com.xj.entity.JasyptRequest;
import com.xj.util.jasypt.JasyptUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;/*** @Author: xjfu* @Create: 2025/07/16 15:18* @Description: Jasypt控制类,用于对铭文进行加密或者解密以及验证数据库密码*/
@RequestMapping(value = "/jasypt",method = RequestMethod.POST)
@RestController
public class JasyptController {@Autowiredprivate JasyptUtil jasyptUtil;@Value("${spring.datasource.password}")private String databasePassword;/*** 加密接口*/@RequestMapping(value = "/encrypt", method = RequestMethod.GET)public String encrypt(@RequestParam String encryptStr) {return jasyptUtil.encrypt(encryptStr);}/*** 解密接口*/@RequestMapping(value = "/decrypt", method = RequestMethod.POST)public String decrypt(@RequestBody JasyptRequest jasyptRequest) {return jasyptUtil.decrypt(jasyptRequest.getDecryptStr());}/*** 测试配置文件中的加密属性是否正确解密*/@GetMapping("/test")public String test() {return "Database password: " + databasePassword;}
}

JasyptRequest.java:

package com.xj.entity;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;import java.io.Serializable;/*** @Author: xjfu* @Create: 2025/07/16 15:25* @Description: Jasypt解密请求体*/
@Data
public class JasyptRequest implements Serializable {private static final long serialVersionUID = -256451235446545L;/***  待解密字符串*/@JsonProperty(value = "decryptStr")private String decryptStr;public String getDecryptStr() {return decryptStr;}public void setDecryptStr(String decryptStr) {this.decryptStr = decryptStr;}
}

application.yml

#默认配置
server:port: 8080# Jasypt配置(必须放在最前面)
#jasypt:
#    encryptor:
#        bean: jasyptStringEncryptor
#        # 可以使用环境变量或命令行参数传入密钥
#        password: ${JASYPT_ENCRYPTOR_PASSWORD:default-secret-key}
#        algorithm: PBEWithMD5AndDES
#        iv-generator-classname: org.jasypt.iv.RandomIvGenerator# 未加密版本
#spring:
#    datasource: #数据源连接信息
#        username: root
#        password: 12345
#        url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8
#        driver-class-name: com.mysql.cj.jdbc.Driver
#    profiles:
#        active: dev #切换配置,指定使用哪个profile# 加密版本
spring:datasource: #数据源连接信息username: ENC(X86Cv+ch9gPTZW7sFcZ+g5NXYUEpSmnB)password: ENC(tO+OKiSXa20LD80vOjWtjDbpf0vf31/x)url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8driver-class-name: com.mysql.cj.jdbc.Driverprofiles:active: dev #切换配置,指定使用哪个profile# 设置 Mybatis 的 xml 保存路径
mybatis-plus:mapper-locations: classpath:mapper/*Mapper.xmltype-aliases-package: com.xj.dao.modelconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImpl #需要lombok框架支持,可以添加# 配置打印 MyBatis 执行的 SQL
logging:level:com:example:demo: debug---
#开发环境
server:port: 8081spring:config:activate:on-profile: dev
---
#测试环境
server:port: 8082spring:config:activate:on-profile: test
---
#生产环境
server:port: 8083spring:config:activate:on-profile: prodlogging:config: classpath:logback-spring.xml #指定使用哪个日志配置文件

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xj</groupId><artifactId>SpringBootStudyProject</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--导入JDBC的场景启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--jquery引入--><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.6.0</version></dependency><!--Thymeleaf 启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--导入数据库驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- MyBatis Plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><!-- junit测试依赖 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><!-- lombok依赖 为了简化实体类的编写代码量 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- Jasypt 加密工具 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version></dependency></dependencies><!--build标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过build中配置的 plugin 来完成--><build><plugins><!--使用SpringBoot的打包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
</project>

3.运行结果

3.1 先将数据库按明文启动,然后获取对应的加密密文

3.1.1 加密

加密URL:

http://127.0.0.1:8081/jasypt/encrypt?encryptStr=root

3.1.2 解密验证

解密URL:

http://127.0.0.1:8081/jasypt/decrypt

报文:

{

    "decryptStr":"X86Cv+ch9gPTZW7sFcZ+g5NXYUEpSmnB"

}

3.2 再将加密密文用ENC()包裹起来替换明文,若启动成功,即为加密成功。

替换:

启动成功:

三、重点说明

1.若解密失败,会包如下错误

2.秘钥最好不要有特殊字符,比如“$”、"_",这样会导致解密失败,实测经验

3.解密JasyptController中的decrypt不应该用@GetMapping,因为解密中的字符春包含很多特殊字符,比如“/”,“+”等,这些都会导致解密失败。@RequestMapping + @RequestParam也不行,必须用@RequestMapping + @RequestBody。

四、感谢:

1.Jasypt概述及整合SpringBoot实现敏感数据加密_jasypt 原理-CSDN博客

2.Jasypt 开源加密库使用教程-CSDN博客

3.springboot 跨域以及jasypt加密使用(第六章)_springboot jasypt-CSDN博客

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

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

相关文章

【电影剖析】千钧一发

目录 1 人物介绍 2 电影名解读 3 电影开头 3.1 电影开头的两段话 3.2 片头设计 4 电影正文 4.1 “杰罗米”各种诡异的行为 4.2 文森特 – 失败的man 4.3 真正的杰罗米以及假基因身份证 4.4 文森特新征程 4.5 基因人的不容易 4.6 睫毛被查出有问题 4.7 文森特身份初…

论文略读:Arcee’s MergeKit: A Toolkit for Merging Large Language Models

emnlp 2024在过去的一年里&#xff0c;开源大型语言模型&#xff08;LLMs&#xff09;迅速发展&#xff0c;并已可通过 Hugging Face 模型库获取。这些模型的训练规模可达数万亿个 token&#xff0c;参数量通常在 1 亿至 700 亿以上不等开源模型检查点涵盖了多种任务&#xff0…

刀客doc:Netflix与YouTube开始在广告战场正面交锋

01广告一开始并不是Netflix的核心业务&#xff0c;但眼下&#xff0c;广告正逐步成为这家公司与YouTube正面对抗的关键战场。在上周刚发布的Q2财报里&#xff0c;Netflix广告层已覆盖全球12个核心市场&#xff0c;月活跃用户已经逼近9400万&#xff0c;主要集中在CTV渗透率高的…

(四)Unity3d-ROS联合仿真:turtlebot在Unity3d中仿真

运行环境Ubuntu20.04Unity3d 1.下载运行 &#xff08;1&#xff09;项目下载地址&#xff1a; Robotics-Nav2-SLAM-Example 最好执行下面命令能将子模块也下载 git clone --recurse-submodule gitgithub.com:Unity-Technologies/Robotics-Nav2-SLAM-Example.gitgit submodu…

信息学奥赛一本通 1553:【例 2】暗的连锁

【题目链接】 ybt 1553&#xff1a;【例 2】暗的连锁 【题目考点】 1. 树上差分&#xff1a;边差分 类似对差分序列进行修改可以完成对原序列的区间修改。对树上边差分进行修改可以完成对树上一条路径中所有边的边权进行修改。 一条边的差分值为该边的权值减去该边连接的深…

二分查找-852.山峰数组的峰顶索引-力扣(LeetCode)

一、题目解析1.山峰数组数据严格满足arr[0]<arr[1]……<arr[i]>arr[i1]……arr[arr.size()-1]2.时间复杂度要求为O(logN)二、算法解析解法1&#xff1a;暴力解法-O(N)遍历数组arr&#xff0c;结合山峰数组性质&#xff0c;我们发现峰顶存在arr[i]>arr[i-1]&#xf…

高可用架构模式——数据集群和数据分区

目录 一、数据集群 1.1、 数据集中集群 1.2、 数据集中集群的复杂度具体体现 1.3、数据分散集群 1.4、数据分散集群的复杂度具体体现 1.5、数据分散集群和数据集中集群的不同点 二、数据分区 2.1、数据分区架构需要考虑的因素 2.1.1、数据量 2.1.2、分区规则 2.1.3、复制规则 2…

上电复位断言的自动化

POR是所有SoC设计的关键功能序列&#xff0c;其作用是将系统从任意状态恢复至正常状态。任何未被检测到的POR缺陷都可能导致实际芯片中的灾难性后果。复杂数量的重置逻辑给验证工程师带来了更大挑战——他们需要在RTL仿真过程中捕捉这些设计缺陷。随着SoC规模和复杂度的持续增长…

2025 年最新 AI 技术:全景洞察与深度解析​

2025 年最新 AI 技术&#xff1a;全景洞察与深度解析​在科技飞速发展的当下&#xff0c;AI 技术无疑是最耀眼的那颗星&#xff0c;持续为我们的生活与工作带来前所未有的变革。步入 2025 年&#xff0c;AI 技术更是呈现出多点突破、全面开花的态势&#xff0c;下面就为大家深入…

Vue项目中的AJAX请求与跨域问题解析

一、AJAX请求方式对比与选型1. 原生XHR方式基本使用示例&#xff1a;缺点分析&#xff1a;代码冗长复杂回调地狱问题需要手动处理JSON转换错误处理不够直观2. jQuery的AJAX基本使用示例&#xff1a;$.ajax({url: http://localhost:5000/api/data,type: GET,success: function(d…

使用 Longformer-base-4096 进行工单问题分类

简述最近接了对Ticket 进行问题分类的任务&#xff0c;使用了prompt和机器学习两种方式来解决&#xff0c;这里重点介绍Longformer-base-4096 模型训练的方案使用 Longformer-base-4096 模型实现文本分类系统&#xff0c;利用 Longformer 处理长序列的能力进行准确分类。该解决…

Matplotlib和Plotly知识点(Dash+Plotly分页展示)

Matplotlib和Plotly知识点&#xff08;DashPlotly分页展示&#xff09;0、Matplotlib、Plotly和Dash区别 &#xff08;推荐用DashPlotly&#xff09;1.1、Matplotlib &#xff08;静态图&#xff09;1. Figures&#xff08;图形&#xff09;概念创建Figure保存和显示Figure2. S…

YOLO12论文阅读:Attention-Centric Real-Time Object Detectors

文章链接&#xff1a; 2502.12524https://arxiv.org/pdf/2502.12524 摘要 (Abstract)​​ 长期以来&#xff0c;增强 YOLO 框架的网络架构至关重要&#xff0c;但尽管注意力机制在建模能力方面已被证明具有优越性&#xff0c;改进却主要集中在基于 CNN 的方面。这是因为基于…

秋招Day17 - Spring - 事务

Spring事务的种类编程式事务和声明式事务介绍一下编程式事务管理&#xff1f;通过编程的方式显式控制事务的开始、提交和回滚&#xff0c;一般使用TransactionTemplate的execute方法介绍一下声明式事务管理&#xff1f;基于AOP&#xff0c;通过调用代理对象拦截目标方法&#x…

多维基分析求导法则

对于n维点R0(I1,I2,I3,......In)如果到R&#xff08;I1&#xff0c; I2 , I3 ,......,In )有基分析求导定理&#xff1a;即R0 R0 *&#xff08;x1 ,x2 ,x3 ,.............xn) R当I1&#xff0c;I2&#xff0c;....,In独立不能转化时有了独立变量的求导和积分不相干法则…

Java值传递和构造函数

一.Java值传递首先我们来看一串代码&#xff1a;输出 10 20&#xff0c;而不是20 10 这是为什么呢&#xff1f;有内存图可以知道&#xff0c;这个change方法所改变的东西最终没有写回到main之中&#xff0c;且他传的是具体的数据&#xff0c;所以还会输出原数据&#xff0c;就相…

电商项目_秒杀_架构及核心

秒杀架构设计先看下普通web项目架构&#xff1a; &#xff08;Nginx : 反向代理、负载均衡&#xff0c;一般是运维部分做生产搭建的时候配置好&#xff09;秒杀架构设计&#xff1a;和普通架构区别&#xff1a;原先由Web 服务或Nginx服务提供的静态资源放到了CDNNginx的职责放⼤…

4x4矩阵教程

4x4矩阵教程 1. 简介 四维矩阵是计算机图形学和3D变换中的重要工具&#xff0c;用于表示三维空间中的仿射变换。本教程将介绍如何使用C实现四维矩阵的基本运算和变换。 2. 代码实现 2.1 头文件 (matrix4x4.h) #ifndef MATRIX4X4_H #define MATRIX4X4_H#include <array> #…

Oracle 数据库共享池与大池调优指南

在 Oracle 数据库的内存管理中&#xff0c;共享池&#xff08;Shared Pool&#xff09;和大池&#xff08;Large Pool&#xff09;是 SGA&#xff08;系统全局区&#xff09;中负责缓存与资源分配的核心组件。合理配置和调优这两个池&#xff0c;能显著提升数据库性能 —— 尤其…

C# Lambdab表达式 Var 类

Lambdab 是用于创建一个方法的表达式Func<参数1类型, 参数2类型, 返回值类型> fnName >(参数1 参数2) {方法代码体}Func<int, int, bool> fnName (int a, int b) > {return a > b; };//调用时和普通方法一致 Console.WriteLine(fnName(10,20)); // false…