热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

springboot+druid数据库的密码加密的两种方式

springboot+druid数据库的密码加密的两种方式,Go语言社区,Golang程序员人脉社

现在很多项目都是把数据库的密码明文放在配置文件中,这样其实是不安全的,应该将密码加密后再放到配置中,这样一定程度的保护数据库密码的安全,那怎么实现呢,这里提供两种方案:

一、实现密码回调逻辑。

大体思路:

  • 预先根据公钥(自定义)生成加密密码,配置在yml文件中
  • 实现加解密算法。
  • 编写自己的回调类,实现自己的回调逻辑,并配置到yml中

1)、配置文件(公钥、密码接口回调类配置)

spring: datasource: # 公钥 publicKey: GOURD-HXNLYW-201314 type: com.alibaba.druid.pool.DruidDataSource master: url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezOne=UTC&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: hWm9HtDn605aupyXTuuA5Q== # 配置 connection-properties,启用加密,配置公钥。 connection-properties: config.decrypt=true;publicKey=${spring.datasource.publicKey};password=${spring.datasource.master.password} passwordCallbackClassName: com.gourd.index.config.DbPasswordCallback slave: url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezOne=UTC&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: hWm9HtDn605aupyXTuuA5Q== # 配置 connection-properties,启用加密,配置公钥。 connection-properties: config.decrypt=true;publicKey=${spring.datasource.publicKey};password=${spring.datasource.slave.password} passwordCallbackClassName: com.gourd.index.config.DbPasswordCallback druid: initial-size: 5 max-wait: 60000 min-idle: 1 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000 validation-query: select 'x' test-while-idle: true test-on-borrow: false test-on-return: false pool-prepared-statements: true max-open-prepared-statements: 50 max-pool-prepared-statement-per-connection-size: 20

2)、加解密工具类(自定义):

import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.codec.binary.Base64; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** * AesHope工具类 * * @author: gourd * **/ @Slf4j public class AesHopeUtil { private static final String KEY_ALGORITHM = "AES"; private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; /*** * AES加密 * @param password * @param content * @return * @throws Exception */ public static String encrypt(String password, String content){ //创建密码器 Cipher cipher = null; try { cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); byte[] bytes = content.getBytes("utf-8"); //初始化密码器 cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(password)); //加密 byte[] bytes1 = cipher.doFinal(bytes); //通过BASE64转码返回 return Base64.encodeBase64String(bytes1); } catch (NoSuchAlgorithmException e) { log.error("{}",e); } catch (NoSuchPaddingException e) { log.error("{}",e); } catch (BadPaddingException e) { log.error("{}",e); } catch (UnsupportedEncodingException e) { log.error("{}",e); } catch (IllegalBlockSizeException e) { log.error("{}",e); } catch (InvalidKeyException e) { log.error("{}",e); } return null; } /*** * AES解密 * @param password * @param content * @return * @throws Exception */ public static String decryt(String password, String content) { Cipher cipher = null; try { cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); //使用密钥初始化解密 cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(password)); byte[] bytes = cipher.doFinal(Base64.decodeBase64(content)); return new String(bytes, "utf-8"); } catch (NoSuchAlgorithmException e) { log.error("{}",e); } catch (NoSuchPaddingException e) { log.error("{}",e); } catch (BadPaddingException e) { log.error("{}",e); } catch (UnsupportedEncodingException e) { log.error("{}",e); } catch (IllegalBlockSizeException e) { log.error("{}",e); } catch (InvalidKeyException e) { log.error("{}",e); } return null; } /*** * 生成加密密钥 * @param password * @return * @throws NoSuchAlgorithmException */ private static SecretKeySpec getSecretKeySpec(final String password) { //返回密钥生成器对象 KeyGenerator keyGenerator = null; try { keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(password.getBytes()); //设置AES密钥长度 keyGenerator.init(128, secureRandom); //生成一个密钥 SecretKey secretKey = keyGenerator.generateKey(); //转换为AES密钥 return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM); } catch (NoSuchAlgorithmException e) { log.error("{}",e); } return null; } }

3)、回调类,实现自己的回调逻辑

import com.alibaba.druid.util.DruidPasswordCallback; import com.gourd.common.utils.AesHopeUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import java.util.Properties; /** * 数据库回调密码解密 * * @author gourd * */ @Component @Slf4j public class DbPasswordCallback extends DruidPasswordCallback { @Override public void setProperties(Properties properties) { super.setProperties(properties); String password = properties.getProperty("password"); String publicKey = properties.getProperty("publicKey"); if (StringUtils.isNotEmpty(password)) { try { //所以这里的代码是将密码进行解密 String sourcePassword = AesHopeUtil.decryt(publicKey, password); setPassword(sourcePassword.toCharArray()); } catch (Exception e) { setPassword(password.toCharArray()); } } } /** * 生成加密后的密码,放到yml中 * @param args */ public static void main(String[] args) { // 生成加密后的密码,放到yml中 String password = "gourd123"; String pwd = AesHopeUtil.encrypt("GOURD-HXNLYW-201314",password); System.out.println(pwd); String source = AesHopeUtil.decryt("GOURD-HXNLYW-201314",pwd); System.out.println(source); } }

Druid多数据源配置请移步:https://blog.csdn.net/HXNLYW/article/details/90519757

二、借助第三方工具(jasypt

1)依赖包:

com.github.ulisesbocchio jasypt-spring-boot-starter 1.16

2)配置秘钥并生成加密文

注:同一个字符加密多次结果不一样,解密后是一样的。

yaml配置:

jasypt: encryptor: password: GOURD-HXN-1314

生成秘钥方式一:

public static void main(String[] args) throws Exception { // jasypt BasicTextEncryptor textEncryptor = new BasicTextEncryptor(); textEncryptor.setPassword("GOURD-HXN-1314"); // 加密 String password = textEncryptor.encrypt("gourd123"); System.out.println("^0^===password:"+ password); // 解密 String originPwd = textEncryptor.decrypt("4M6RKeFuZ7OngpmunjkMm/a+W8eCJrsF"); System.out.println("^0^===originPwd:"+ originPwd); }

生成秘钥方式二:

在CMD中cd到jar包路径下执行语句(input:明文信息,password:秘钥):

java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="hxnlyw123" password=GOURD-HXN-1314 algorithm=PBEWithMD5AndDES

操作截图:

3)将OUTPUT内容替换数据库明文密码并加解密函数:

jasypt: encryptor: password: GOURD-HXN-1314 spring: datasource: # 公钥 type: com.alibaba.druid.pool.DruidDataSource master: url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezOne=UTC&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ENC(4M6RKeFuZ7OngpmunjkMm/a+W8eCJrsF) slave: url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezOne=UTC&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ENC(4M6RKeFuZ7OngpmunjkMm/a+W8eCJrsF)

 到此配置完成。redis密码、邮件密码都可以用此方式加密


推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 2018深入java目标计划及学习内容
    本文介绍了作者在2018年的深入java目标计划,包括学习计划和工作中要用到的内容。作者计划学习的内容包括kafka、zookeeper、hbase、hdoop、spark、elasticsearch、solr、spring cloud、mysql、mybatis等。其中,作者对jvm的学习有一定了解,并计划通读《jvm》一书。此外,作者还提到了《HotSpot实战》和《高性能MySQL》等书籍。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • RabbitMq之发布确认高级部分1.为什么会需要发布确认高级部分?在生产环境中由于一些不明原因,导致rabbitmq重启,在RabbitMQ重启期间生产者消息投递失败,导致消息丢 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
author-avatar
淡定_一辈子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有