spring boot集成jasypt 并 实现自定义加解密

一. 技术需求

由于项目中的配置文件 配置的地方过多,现将配置文件统一放到nacos上集中管理 且密码使用加密的方式放在配置文件中

项目中组件使用的版本环境如下
spring cloud 2021.0.5
spring cloud alibaba 2021.0.5.0
spring boot 2.6.13

二. 技术实现

配置文件的加密使用 加密库 jasypt

三. 简单使用步骤

  • 引入maven依赖

    <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version>
    </dependency>
    
  • 添加配置

    #加解密使用的密码 可以理解为密钥
    jasypt.encryptor.password=12581
    
  • 使用jasypt配置的密码来加密密码 并替换配置原先密码 (提供工具类进行加密)

    #原密码
    spring.datasource.passsword=1232456
    #新的密码 其实 rngDAJwRU09A3oNLkxzNaP3wfyhHt5N4DPAjudNJKDYAWXDeFmdGcFvgZJSh4gqZ 为源密码加密后的值
    spring.datasource.password=ENC(rngDAJwRU09A3oNLkxzNaP3wfyhHt5N4DPAjudNJKDYAWXDeFmdGcFvgZJSh4gqZ)
    

工具类如下

@Slf4j
public class Custom {public static void main(String[] args) {PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();SimpleStringPBEConfig config = new SimpleStringPBEConfig();//TODO 替换为配置文件中的密码config.setPassword("12581");//默认的加密算法config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");config.setKeyObtentionIterations("1000");config.setPoolSize("1");config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");config.setStringOutputType("base64");encryptor.setConfig(config);//TODO 123456 替换为所需加密的 原文String encrypt = encryptor.encrypt("123456");log.info("encrypt: {}", encrypt);}
}

到此就完成基本的配置文件加解密

你以为结束了吗,no~~~~

四. 高级使用篇

上面使用的默认的加解密的工具类,但是jasypt.encryptor.password 还是需要配置在配置文件中的 (配置文件、jvm参数等)本质来讲还是容易统一泄露。到这里,可能就有灵感了。不如我们自定义的加密的工具类 复杂的话 也可以搞个非对称加密(这个可自行研究)

目前我们来使用下 自定义加密的工具

(1)首先实现自定义的加密工具 需要实现 StringEncryptor 即可 我们这是用的国密4的对称加密算法 同时使用了 hutool的工具类

import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SM4;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.jasypt.encryption.StringEncryptor;import java.nio.charset.StandardCharsets;/*** @author leon* @date 2023-08-19 10:54:32*/
@Slf4j
public class Sm4Encryptor implements StringEncryptor {private static final SM4 SM_4;static {byte[] key = "1234567891234560".getBytes();byte[] iv = "1234567891234560".getBytes();SM_4 = new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv);}@Overridepublic String encrypt(String message) {return SM_4.encryptHex(message);}@Overridepublic String decrypt(String encryptedMessage) {return SM_4.decryptStr(encryptedMessage);}public static void main(String[] args) {String originalValue = "123456";String encrypted = SM_4.encryptHex(originalValue);String decrypted = SM_4.decryptStr(encrypted);log.info("Original Value: {}" , originalValue);log.info("Encrypted Value: {}" , encrypted);log.info("Decrypted Value: {}", decrypted);}}

(2)注册该bean 这需要使用特殊的方式注册bean 因为我们希望在 Spring Boot 应用程序启动期间提前将自定义的加解密类添加到 Spring 的应用程序上下文中,以便在配置文件加载之前,加解密类已经可用。这样可以确保配置文件中的加密属性能够在加载时使用正确的自定义加解密逻辑进行解密

新建初始化类

import com.stlye.encryptor.Sm4Encryptor;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;/*** @date 2023-08-21 13:57:20* @author leon*/
public class CustomContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {applicationContext.getBeanFactory().registerSingleton("encryptorBean", new Sm4Encryptor());}
}

其次在resource 下新建 META_INF文件夹 并新建 spring.factories 文件

org.springframework.context.ApplicationContextInitializer=com.style.order.config.CustomContextInitializer

(3)调整配置

#移除该配置 
jasypt.encryptor.password=12581#新增如下配置 自定义加解密工具的bean名称 
jasypt.encryptor.bean=encryptorBean

(4) 使用该工具类生成需要加密的内容 并替换 原配置文件中的内容

#其中cab60ba208f8a7d87c4f631e2763607a为源密码加密后的内容
spring.datasource.password=ENC(cab60ba208f8a7d87c4f631e2763607a)#另外属性解密的前缀和后缀都是支持自定义 默认如下
jasypt.encryptor.property.prefix=ENC(
jasypt.encryptor.property.suffix=)

到这里就完成配置的文件的加密 你肯定会好奇,解密需要我们自己做么,回答当然不需要,这个框架中已经自动帮我们进行了解密

具体的实现原理可看源码类 EnableEncryptablePropertiesBeanFactoryPostProcessor 和 EncryptablePropertyResolverConfiguration 两大核心类 本质上来讲也是动态代理。

以下是国密4加密算法的参数介绍


密码的加密算法选择了 SM4 国密的对称加密算法

内置参数 模式和补码方式对比如下

//不同的模式和补码方式在加密算法中有不同的作用,它们会影响加密和解密的行为以及安全性。下面我会简要解释一下不同模式和补码方式的区别,并提供一些关于安全性的信息:
//
//**模式(Mode)**:
//加密模式定义了数据块之间是如何加密的,它影响到同一消息分成多个数据块时的加密方式。以下是一些常见的加密模式:
//
//1. **ECB(Electronic Codebook)**:每个数据块都独立加密,相同的输入会得到相同的输出。不适合加密大量数据,安全性较差。
//
//2. **CBC(Cipher Block Chaining)**:前一个数据块的加密结果会与当前数据块一起进行加密。需要一个初始化向量(IV)来增加安全性。
//
//3. **CFB(Cipher Feedback)**:前一个密文块被解密并与当前明文块进行异或操作,然后再进行加密。不需要 IV。
//
//4. **OFB(Output Feedback)**:类似于 CFB,但是前一个密文块只用于生成密钥流,不直接与明文块进行操作。不需要 IV。
//
//5. **CTR(Counter)**:将 IV 与一个计数器组合,生成密钥流,然后与明文块进行异或操作。不需要 IV。
//
//**补码方式(Padding)**:
//补码方式是在加密块大小与数据大小不匹配时,如何填充数据块的方式。以下是一些常见的补码方式:
//
//1. **NoPadding**:不进行任何填充,要求明文的大小必须是加密块大小的倍数。
//
//2. **PKCS5Padding** / **PKCS7Padding**:在数据块的末尾填充字节,字节的值等于需要填充的字节数。
//
//3. **ISO10126Padding**:在数据块的末尾填充随机字节,最后一个字节指示填充的字节数。
//
//4. **ZeroBytePadding**:在数据块的末尾填充零字节。
//
//**安全性评估**:
//安全性评估涉及多个因素,包括加密算法的强度、密钥的管理、数据传输的安全性等。在选择加密模式和补码方式时,要根据具体的应用场景和安全需求进行权衡。一般而言,以下是一些建议:
//
//- **模式选择**:CBC 模式相对较为常见和安全,适用于大多数场景。CTR 也是一种常见的选择,适合并行加解密。
//
//- **补码方式选择**:PKCS7Padding / PKCS5Padding 是常见的选择,它们会根据需要填充的字节数进行填充,相对比较安全。
//
//总之,选择加密模式和补码方式时,应该综合考虑性能、安全性和适用性。在设计和实现加密系统时,最好参考专业的加密标准和最佳实践,以确保数据的安全性。

其中安全性较高 mode参数可选择值的是 CBC / GCM

在国密4(SM4)加密算法中,GCM(Galois/Counter Mode)和CBC(Cipher Block Chaining)都是加密模式,用于定义不同的加密操作方式。它们有一些区别,包括加密过程、性能、安全性等方面。

  1. GCM模式(Galois/Counter Mode):

    • GCM是一种高级的分组加密模式,除了提供加密和解密功能外,还具有认证和完整性校验的能力。
    • GCM模式在加密过程中会使用一个称为"Nonce"的值,用于确保每个加密操作的唯一性,避免重复使用Nonce导致的安全问题。
    • GCM模式可以同时进行加密和认证,因此在一些场景中可以减少通信的复杂性和性能开销。
    • 由于GCM模式的性能较高且提供了认证能力,通常在需要较高性能和安全性的场景中被使用。
  2. CBC模式(Cipher Block Chaining):

    • CBC是一种较为传统的分组加密模式,每个分组的密文会依赖于前一个分组的明文,因此具有一定的关联性。
    • CBC模式需要在加密前进行填充操作,以适应固定长度的分组大小。
    • 由于每个分组的加密都依赖于前一个分组的密文,所以在并行处理时可能存在性能上的限制。
    • CBC模式通常需要额外的认证步骤来保证数据完整性和安全性。

性能方面,GCM模式通常在处理大量数据时具有更好的性能,因为它可以同时进行加密和认证,而且不需要像CBC那样需要明确的填充步骤。然而,由于GCM模式引入了额外的认证计算,对于较小的数据块,GCM的性能可能会略逊于CBC。

选择合适的加密模式取决于具体的应用场景和需求。如果你需要高性能和认证能力,可以考虑使用GCM模式。如果你更关注传统的分组加密模式,并且不需要认证能力,可以选择CBC模式。

GCM 由于使用一个称为"Nonce"的值,每次加密都需要保证唯一 ,每次需要新建实例 ,避免重复使用Nonce导致的安全问题 这就导致了性能来讲可能稍逊于 CBC 且GCM模式 不需要补码

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

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

相关文章

68个Python内置函数,你不会不知道吧?

内置函数就是Python给你提供的&#xff0c;拿来直接用的函数&#xff0c;比如print.&#xff0c;input等。 截止到python版本3.6.2 &#xff0c;python一共提供了68个内置函数&#xff0c;具体如下&#x1f447; abs() dict() help() min() …

ARM开发(cortex-A7核,UART总线实验)

目标&#xff1a;键盘输入一个字符a,串口工具显示b&#xff1b; 键盘输入一个字符串"nihao",串口工具显示"nihao"&#xff1b; ---.h头文件--- #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_rcc.h" #include "stm32mp1x…

根据Dockerfile创建容器案例讲解

-f为dokerfile的路径&#xff0c; -t为新镜像的名称及版本。 后面这个点是寻址路径。

阿里面试官常问的TCP和UDP,你真的弄懂了吗?

♥ 前 言 作为软件测试&#xff0c;大家都知道一些常用的网络协议是我们必须要了解和掌握的&#xff0c;面试的时候面试官也非常喜欢问一些协议相关的问题&#xff0c;其中有两个协议因为非常基础&#xff0c;出现的频率非常之高&#xff0c;分别是 ”TCP 协议“ 和 ”UDP 协…

漏洞指北-VulFocus靶场专栏-中级03

漏洞指北-VulFocus靶场专栏-初级03 中级009 &#x1f338;gxlcms-cve_2018_14685&#x1f338;step1&#xff1a;安装系统 密码rootstep2 进入后台页面 账号密码&#xff1a;admin amdin888step3 查看详细 有phpinfo() 中级010 &#x1f338;dedecms-cnvd_2018_01221&#x1f3…

2023国赛数学建模C题思路模型代码 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…

TypeError: Object of type int64 is not JSON serializable

TypeError: Object of type int64 is not JSON serializable 这个错误通常意味着你试图将一个Python对象转换为JSON&#xff0c;但是这个对象不能被序列化为JSON。在你的情况下&#xff0c;错误发生在尝试将一个int64类型的对象转换为JSON时。 在Pandas中&#xff0c;当你使用…

《游戏编程模式》学习笔记(五)原型模式 Prototype Pattern

原型的定义 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 举个例子 假设我现在要做一款游戏&#xff0c;这个游戏里有许多不同种类的怪物&#xff0c;鬼魂&#xff0c;恶魔和巫师。这些怪物通过“生产者”进入这片区域&#xff0c;每种敌人…

element文本域禁止手动拉伸、两种方式、textarea

文章目录 style方式element自带的禁止拉伸方法建议 style方式 html <el-inputv-model"content":rows"3"class"r_n"type"textarea"maxlength"40"placeholder""style"height: 100%;" />css style…

等保测评--安全计算环境--测评方法

安全子类--身份鉴别 a)应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换; 一、测评对象 终端和服务器等设备中的操作系统(包括宿主机和虚拟机操作系统) 、网络设备(包括虚拟网络设备)、安全设备(包括虚拟安全设备)、移动终端…

Qt多线程开启定时任务

项目场景&#xff1a; 多线程执行一些耗时操作&#xff0c;并且需要固定时间去轮询。 代码&#xff1a; #include <QThread> #include <QTimer> #include <QtCore/QMutex>class pollingManager : public QObject {Q_OBJECTpublic:static pollingManager*get…

Linux 桌面版关闭GUI桌面环境

持久打开和关闭 通过CtrlAltF1-F6快捷键进入命令行界面 执行以下命令&#xff0c;持久关闭Ubuntu桌面版的GUI环境&#xff1a; sudo systemctl set-default multi-user.target执行以下命令&#xff0c;持久开启Ubuntu桌面版的GUI环境 通过CtrlAltF7快捷键进入GUI界面 sudo s…

Android Studio 之 Android 中使用 HanLP 进行句子段落的分词处理(包括词的属性处理)的简单整理

Android Studio 之 Android 中使用 HanLP 进行句子段落的分词处理&#xff08;包括词的属性处理&#xff09;的简单整理 目录 Android Studio 之 Android 中使用 HanLP 进行句子段落的分词处理&#xff08;包括词的属性处理&#xff09;的简单整理 一、简单介绍 二、实现原理…

派森 #P122. 峰值查找

描述 给定一个长度为n的列表nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 &#xff08;1&#xff09;峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于&#xff1b; &…

Unity 之 RaycastHit(存储射线投射操作)

文章目录 总述具体使用场景 总述 RaycastHit 类是 Unity 中的一个结构&#xff0c;用于存储射线投射操作的结果。射线投射是一种常用的技术&#xff0c;用于检测场景中的碰撞、获取碰撞点、获取碰撞对象的信息等。RaycastHit 提供了关于射线与场景中对象的交互信息&#xff0c…

Vue3中ref和reactive的使用

今天在项目中使用reactive过程中出现变量无法更新视图&#xff0c;reactive通常用于对象 <template><div class"wrapper"><el-checkbox :indeterminate"isInderterminate" v-model"checkAll" change"handleCheckAllChange&…

限制 el-input 输入 emoji

1. 电脑如何输入 emoji 表情 ? 快捷键 win; 或 win. 2. 代码实现 <template><el-input v-model"input" placeholder"请输入内容" input"inputChange"></el-input> </template><script> export default {name: D…

R语言实现免疫浸润分析(1)

免疫浸润分析是生物信息学研究中的一项关键内容&#xff0c;它旨在评估肿瘤微环境中不同类型的免疫细胞组成。免疫细胞在肿瘤发展和治疗中起着至关重要的作用&#xff0c;因为它们可以影响肿瘤的生长、扩散和对治疗的响应。 为了了解免疫细胞在肿瘤中的分布和数量&#xff0c;…

LC-路径总和

LC-路径总和 链接&#xff1a;https://leetcode.cn/problems/path-sum/description/ 描述&#xff1a;给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。…

安防监控视频汇聚平台EasyCVR视频平台调用iframe地址无法播放的问题解决方案

安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、视频云存储、视频集中存储、视频存储磁盘阵列、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、AI算法中台智能分析无缝…