jeecg spring数据源用户名和密码加密 避免明文安全漏洞

1.目的

由于系统部署在互联网,配置文件中的数据库账号密码使用明文,存在安全隐患,做等保测试时要求对其加密。

2.实现方法

Jeecg框架本身有PasswordUtil可以使用PBEWITHMD5andDES进行加密,这里为方便改造,且安全性较高,故选择使用此加密方式进行加密。
附:PasswordUtil代码

package org.jeecgframework.core.util;import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class PasswordUtil {/*** JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES* PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1* *//*** 定义使用的算法为:PBEWITHMD5andDES算法*/public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法public static final String Salt = "63293188";//密钥/*** 定义迭代次数为1000次*/private static final int ITERATIONCOUNT = 1000;/*** 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节* * @return byte[] 盐值* */public static byte[] getSalt() throws Exception {// 实例化安全随机数SecureRandom random = new SecureRandom();// 产出盐return random.generateSeed(8);}public static byte[] getStaticSalt() {// 产出盐return Salt.getBytes();}/*** 根据PBE密码生成一把密钥* * @param password*            生成密钥时所使用的密码* @return Key PBE算法密钥* */private static Key getPBEKey(String password) {// 实例化使用的算法SecretKeyFactory keyFactory;SecretKey secretKey = null;try {keyFactory = SecretKeyFactory.getInstance(ALGORITHM);// 设置PBE密钥参数PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());// 生成密钥secretKey = keyFactory.generateSecret(keySpec);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return secretKey;}/*** 加密明文字符串* * @param plaintext*            待加密的明文字符串* @param password*            生成密钥时所使用的密码* @param salt*            盐值* @return 加密后的密文字符串* @throws Exception*/public static String encrypt(String plaintext, String password, byte[] salt) {Key key = getPBEKey(password);byte[] encipheredData = null;PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, ITERATIONCOUNT);try {Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);encipheredData = cipher.doFinal(plaintext.getBytes());} catch (Exception e) {}return bytesToHexString(encipheredData);}/*** 解密密文字符串* * @param ciphertext*            待解密的密文字符串* @param password*            生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)* @param salt*            盐值(如需解密,该参数需要与加密时使用的一致)* @return 解密后的明文字符串* @throws Exception*/public static String decrypt(String ciphertext, String password, byte[] salt) {Key key = getPBEKey(password);byte[] passDec = null;PBEParameterSpec parameterSpec = new PBEParameterSpec(getStaticSalt(), ITERATIONCOUNT);try {Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);passDec = cipher.doFinal(hexStringToBytes(ciphertext));}catch (Exception e) {// TODO: handle exception}return new String(passDec);}/*** 将字节数组转换为十六进制字符串* * @param src*            字节数组* @return*/public static String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder("");if (src == null || src.length <= 0) {return null;}for (int i = 0; i < src.length; i++) {int v = src[i] & 0xFF;String hv = Integer.toHexString(v);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}/*** 将十六进制字符串转换为字节数组* * @param hexString*            十六进制字符串* @return*/public static byte[] hexStringToBytes(String hexString) {if (hexString == null || hexString.equals("")) {return null;}hexString = hexString.toUpperCase();int length = hexString.length() / 2;char[] hexChars = hexString.toCharArray();byte[] d = new byte[length];for (int i = 0; i < length; i++) {int pos = i * 2;d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));}return d;}private static byte charToByte(char c) {return (byte) "0123456789ABCDEF".indexOf(c);}public static void main(String[] args) {int i=10;for (int j = 0; j < i; j++) {if((j)%3==0){System.out.print("<br>");}else {System.out.print(j);}}System.out.print(-1%2==0);String str = "root";String password = "root";org.jeecgframework.core.util.LogUtil.info("明文:" + str);org.jeecgframework.core.util.LogUtil.info("密码:" + password);try {byte[] salt = PasswordUtil.getStaticSalt();String ciphertext = PasswordUtil.encrypt(str, password, salt);org.jeecgframework.core.util.LogUtil.info("密文:" + ciphertext);String plaintext = PasswordUtil.decrypt(ciphertext, password, salt);org.jeecgframework.core.util.LogUtil.info("明文:" + plaintext);String result = PasswordUtil.decrypt("ea3d519525358e00", "root", salt);org.jeecgframework.core.util.LogUtil.info("明文:" + result);} catch (Exception e) {e.printStackTrace();}}
}
2.1、加密方式

先通过加密方法把将要加密的数据进行加密,我这边是对数据库用户名和密码都加密处理
在这里插入图片描述
加密后数据库配置文件
在这里插入图片描述

2.2 spring-mvc-hibernate.xml中配置并添加一个类继承PropertyPlaceholderConfigurer实现使用加密字符串,使用时解密

在这里插入图片描述
EncryptPropertyPlaceholderConfigurer.java

package org.jeecgframework.core.config;import org.apache.commons.lang.ObjectUtils;
import org.jeecgframework.core.util.PasswordUtil;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {/** 需要解密的字段 */private String[] encryptPropNames = { "jdbc.username.jeecg", "jdbc.password.jeecg" };
//    private String[] encryptPropNames = {  "jdbc.password.jeecg" };protected String convertProperty(String propertyName, String propertyValue) {if (isEncryptProp(propertyName)) {// 解密(根据实际内容改成具体解密方法)return PasswordUtil.decrypt(propertyValue,"password",PasswordUtil.getStaticSalt());} else {return propertyValue;}}/*** 判断属性是否需要解密** @param propertyName* @return*/@SuppressWarnings("deprecation")private boolean isEncryptProp(String propertyName) {for (String encryptpropertyName : encryptPropNames) {if (ObjectUtils.equals(encryptpropertyName, propertyName)) {return true;}}return false;}
}

不详之处可参考:sping数据源中使用加密的用户名和密码

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

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

相关文章

探索数据分析无限潜能:vividime Desktop助力企业智能决策

在数字化浪潮席卷全球的今天&#xff0c;数据已经成为企业最宝贵的资产之一。通过对海量数据的深度挖掘和分析&#xff0c;企业能够洞察市场趋势、优化运营流程、提升用户体验&#xff0c;从而在激烈的市场竞争中脱颖而出。永洪科技的vividime Desktop作为一款功能强大、操作简…

Scala语言:大数据开发的未来之星 - 零基础到精通入门指南

前言 随着大数据时代的到来&#xff0c;数据量的急剧增长为软件开发带来了新的挑战和机遇。Scala语言因其函数式编程和面向对象的特性&#xff0c;以及与Apache Spark的完美协作&#xff0c;在大数据开发领域迅速崛起&#xff0c;成为该领域的新兴宠儿。本篇将从零基础开始&…

【Java】Object、Objects、包装类、StringBuilder、StringJoiner

目录 1.API2.Object类3.Objects类4.包装类4.1包装类概述4.2包装类的其他常见操作 5.StringBuilder 可变字符串5.1概述5.2StringBuilder案例 6.StringJoiner 1.API API&#xff1a;应用程序编程接口&#xff0c;全称application programing interface&#xff0c;即Java已经写好…

从粉丝基础到带货数据:全方位解读TikTok带货达人的选择之道

在如今的数字营销时代&#xff0c;TikTok已成为品牌推广和产品销售的重要平台。通过与合适的TikTok带货达人合作&#xff0c;品牌可以迅速吸引大量的潜在客户&#xff0c;实现销售转化。然而&#xff0c;选择合适的TikTok达人需要慎重考虑多个因素。本文Nox聚星将和大家详细阐述…

Android入门第68天-自动更新/升级怎么做(生产级实例)

开篇 今天我们进入第68讲。 在第60天左右其实很多同学们已经进入了APP应用开发了,因为60天内容足以让大家踏上正实的Android开发生涯。 随着开发的深入,我们发觉日常工作中无非就是一些组件的嵌套、合理应用。当代码迭代、功能迭代越来越频繁后我们面临着另一个问题,即:…

mac禁用电池睡眠-mac盒盖连接显示器

mac禁用电池睡眠-mac盒盖连接显示器-mac断点盒盖连接显示器 讲解&#xff1a;mac盒盖的时候连接显示器会睡眠并断开和显示器的连接&#xff0c;只有在电池->选项->选择使用电源适配器的时候防止睡眠&#xff0c;才可以连接电源线外界显示器 但是苹果的电池相当于手机电…

hdfs文件系统增删查原理

目录 1、hdfs读取文件原理 1.1、读取流程图解 1.2、架构层面读取流程详解 1.3、源码层面读取流程详解 2、hdfs写入文件原理 2.1、写入流程图解 2.2、架构层面写入流程 2.3、源码层面写入流程 3、hdfs删除文件原理 3.1、删除文件图解 3.2、架构层面删除流程 3.3、源码…

Gobject tutorial 七

The GObject base class GObject是一个fundamental classed instantiatable type,它的功能如下&#xff1a; 内存管理构建/销毁实例set/get属性方法信号 /*** GObjectClass:* g_type_class: the parent class* constructor: the constructor function is called by g_object…

云徙科技助力竹叶青实现用户精细化运营,拉动全渠道销售额增长

竹叶青茶以其别具一格的风味与深厚的历史底蕴&#xff0c;一直被誉为茶中瑰宝。历经千年的传承与创新&#xff0c;竹叶青不仅坚守着茶叶品质的极致追求&#xff0c;更在数字化的浪潮中&#xff0c;率先打破传统&#xff0c;以科技力量赋能品牌&#xff0c;成为茶行业的领军者。…

家长必备:超全的VIP硬笔书法课程(250课完结版),手把手教附可打印控笔素材!

今天要跟大家聊聊一个特别有意思的玩意儿——硬笔书法。你没听错&#xff0c;就是那种用钢笔、圆珠笔&#xff0c;甚至铅笔就能写出漂亮字的技艺。这可不仅仅是写字那么简单&#xff0c;它是一门艺术&#xff0c;一种生活的态度。 阿星记得小时候&#xff0c;爷爷总是拿着毛笔…

http缓存及http2配置

http缓存及http2配置极大提高了网页加载得速度 1.1 nginx安装 首先是需要安装nginx 去官网下载windows版本的安装包 nginx 命令 nginx start //启动 nginx -s stop nginx -s reload // 重新运行 tasklist /fi "imagename eq nginx.exe" //进程 把打包好的文件copy…

PyTorch -- RNN 快速实践

RNN Layer torch.nn.RNN(input_size,hidden_size,num_layers,batch_first) input_size: 输入的编码维度hidden_size: 隐含层的维数num_layers: 隐含层的层数batch_first: True 指定输入的参数顺序为&#xff1a; x&#xff1a;[batch, seq_len, input_size]h0&#xff1a;[batc…

使用密钥对登录服务器

目录 1、使用密钥文件登录服务器 2、登录成功画面&#xff1a; 3、如若出现以下状况&#xff0c;则说明密钥文件登录失败 1、使用密钥文件登录服务器 首先需要上传pem文件 2、登录成功画面&#xff1a; 3、如若出现以下状况&#xff0c;则说明密钥文件登录失败 解决方法&…

嵌入式技术学习——Linux环境编程(高级编程)——shell编程

一、shell编程的基础介绍 1.为什么要进行shell编程? 在Linux系统中&#xff0c;虽然有各种各样的图形化接口工具&#xff0c;但是shell仍然是一个非常灵活的 工具。 Shell不仅仅是命令的收集&#xff0c;而且是一门非常棒的编程语言。 您可以通过使用shell使大量的任务自动化…

mfc140.dll电脑文件丢失的处理方法,这4种方法能快速修复mfc140.dll

mfc140.dll文件是一个非常重要的dll文件&#xff0c;如果它丢失了&#xff0c;那么会严重的影响程序的运行&#xff0c;这时候我们要找方法去修复mfc140.dll这个文件&#xff0c;那么你知道怎么修复么&#xff1f;如果不知道&#xff0c;那么不妨看看下面的mfc140.dll文件丢失的…

【DAMA】掌握数据管理核心:CDGA考试指南

引言&#xff1a;        在当今快速发展的数字化世界中&#xff0c;数据已成为组织最宝贵的资产之一。有效的数据管理不仅能够驱动业务决策&#xff0c;还能提升竞争力和市场适应性。DAMA国际一直致力于数据管理和数字化的研究、实践及相关知识体系的建设。秉承公益、志愿…

集合系列(二十六) -利用LinkedHashMap实现一个LRU缓存

一、什么是 LRU LRU是 Least Recently Used 的缩写&#xff0c;即最近最少使用&#xff0c;是一种常用的页面置换算法&#xff0c;选择最近最久未使用的页面予以淘汰。 简单的说就是&#xff0c;对于一组数据&#xff0c;例如&#xff1a;int[] a {1,2,3,4,5,6}&#xff0c;…

SpringBoot配置第三方专业缓存技术Ehcache

Ehcache缓存技术 我们刚才是用Springboot提供的默认缓存技术 我们用的是simple 是一个内存级的缓存 我们接下来要使用专业的缓存技术了 Ehcache 是一个流行的开源 Java 分布式缓存&#xff0c;由 Terracotta 公司开发和维护。它提供了一个快速、可扩展、易于集成的内存缓存…

如何制定适合不同行业的新版FMEA培训计划?

在快速变化的市场环境中&#xff0c;失效模式与影响分析&#xff08;FMEA&#xff09;作为一种预防性的质量控制工具&#xff0c;越来越受到企业的重视。然而&#xff0c;不同行业在FMEA应用上存在着明显的差异&#xff0c;因此制定适合不同行业的新版FMEA培训计划显得尤为重要…

Sui主网升级至V1.27.2版本

其他升级要点如下所示&#xff1a; 重点&#xff1a; #17245 增加了一个新的协议版本&#xff0c;并在开发网络上启用了Move枚举。 JSON-RPC #17245: 在返回的JSON-RPC结果中增加了对Move枚举值的支持。 GraphQL #17245: 增加了对Move枚举值和类型的支持。 CLI #179…