引言

咱们公司从事的是信息安全涉密应用的一些项目研发一共有分为三步,相比较于一般公司和一般的项目,对于信息安全要求更加严格,领导要求数据量和用户的用户名及密码信息都必需是要密文配置和存储的,这就涉及到jdbc.properties文件中的数据库的用户名和密码也是一样的,需要配置问密文,在连接的时候再加载解密为明文进行数据库的连接操作,以下就是实现过程,一共有分为三步。

一、创建DESUtil类

提供自定义密钥,加密解密的方法。

  1. package com.hzdy.DCAD.common.util;
  2.  
  3. import sun.misc.BASE64Decoder;
  4. import sun.misc.BASE64Encoder;
  5. import javax.crypto.Cipher;
  6. import javax.crypto.KeyGenerator;
  7. import java.security.Key;
  8. import java.security.SecureRandom;
  9.  
  10. /**
  11. * Created by Wongy on 2019/8/8.
  12. */
  13. public class DESUtil {
  14. private static Key key;
  15. //自己的密钥
  16. private static String KEY_STR = "mykey";
  17.  
  18. static {
  19. try {
  20. KeyGenerator generator = KeyGenerator.getInstance("DES");
  21. SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
  22. secureRandom.setSeed(KEY_STR.getBytes());
  23. generator.init(secureRandom);
  24. key = generator.generateKey();
  25. generator = null;
  26. } catch (Exception e) {
  27. throw new RuntimeException(e);
  28. }
  29. }
  30.  
  31. /**
  32. * 对字符串进行加密,返回BASE64的加密字符串
  33. *
  34. * @param str
  35. * @return
  36. * @see [类、类#方法、类#成员]
  37. */
  38. public static String getEncryptString(String str) {
  39. BASE64Encoder base64Encoder = new BASE64Encoder();
  40. try {
  41. byte[] strBytes = str.getBytes("UTF-8");
  42. Cipher cipher = Cipher.getInstance("DES");
  43. cipher.init(Cipher.ENCRYPT_MODE, key);
  44. byte[] encryptStrBytes = cipher.doFinal(strBytes);
  45. return base64Encoder.encode(encryptStrBytes);
  46. } catch (Exception e) {
  47. throw new RuntimeException(e);
  48. }
  49.  
  50. }
  51.  
  52. /**
  53. * 对BASE64加密字符串进行解密
  54. *
  55. */
  56. public static String getDecryptString(String str) {
  57. BASE64Decoder base64Decoder = new BASE64Decoder();
  58. try {
  59. byte[] strBytes = base64Decoder.decodeBuffer(str);
  60. Cipher cipher = Cipher.getInstance("DES");
  61. cipher.init(Cipher.DECRYPT_MODE, key);
  62. byte[] encryptStrBytes = cipher.doFinal(strBytes);
  63. return new String(encryptStrBytes, "UTF-8");
  64. } catch (Exception e) {
  65. throw new RuntimeException(e);
  66. }
  67.  
  68. }
  69.  
  70. public static void main(String[] args) {
  71. String name = "dbuser";
  72. String password = "waction2016";
  73. String encryname = getEncryptString(name);
  74. String encrypassword = getEncryptString(password);
  75. System.out.println("encryname : " + encryname);
  76. System.out.println("encrypassword : " + encrypassword);
  77.  
  78. System.out.println("name : " + getDecryptString(encryname));
  79. System.out.println("password : " + getDecryptString(encrypassword));
  80. }
  81. }

二、 创建EncryptPropertyPlaceholderConfigurer类

建立与配置文件的关联。

  1. package com.hzdy.DCAD.common.util;
  2.  
  3. import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
  4.  
  5. public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
  6. //属性需与配置文件的KEY保持一直
  7. private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};
  8.  
  9. @Override
  10. protected String convertProperty(String propertyName, String propertyValue) {
  11.  
  12. //如果在加密属性名单中发现该属性
  13. if (isEncryptProp(propertyName)) {
  14. String decryptValue = DESUtil.getDecryptString(propertyValue);
  15. System.out.println(decryptValue);
  16. return decryptValue;
  17. } else {
  18. return propertyValue;
  19. }
  20.  
  21. }
  22.  
  23. private boolean isEncryptProp(String propertyName) {
  24. for (String encryptName : encryptPropNames) {
  25. if (encryptName.equals(propertyName)) {
  26. return true;
  27. }
  28. }
  29. return false;
  30. }
  31. }

三、 修改配置文件 jdbc.properties

  1. #加密配置之前
  2. #jdbc.driver=com.mysql.jdbc.Driver
  3. #jdbc.user=root
  4. #jdbc.password=root
  5. #jdbc.url=jdbc:mysql://localhost:3306/bookstore
  6.  
  7. #加密配置之后
  8. jdbc.driver=com.mysql.jdbc.Driver
  9. jdbc.user=Ov4j7fKiCzY=
  10. jdbc.password=Ov4j7fKiCzY=
  11. jdbc.url=jdbc:mysql://localhost:3306/bookstore

四、 修改spring-content.xml配置文件

  1. spring-context中的
  2. <context:property-placeholder location="classpath:.properties" />
  3. 修改为
  4. <bean class="com.hzdy.DCAD.common.util.EncryptPropertyPlaceholderConfigurer"p:locations="classpath:*.properties"/>
  5. //注意只能存在一个读取配置文件的bean,否则系统只会读取最前面的

   注意:如果发现配置密文的username和password可以加载并解密成功,但是最后连接的时候还是以密文连接并报错,这可能涉及到内存预加载的问题,项目一启动,程序会加密密文的用户名和密码,就算最后解密成功了,最后连接数据库读取的却还是密文,这时候我们可以自己重写连接池的方法,让spring-content.xml加载重写的连接池方法,并在连接的时候再提前进行解密。

  1. package com.thinkgem.jeesite.common.encrypt;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.SQLException;
  5. import java.util.Properties;
  6.  
  7. import javax.security.auth.callback.PasswordCallback;
  8. import com.alibaba.druid.util.DruidPasswordCallback;
  9.  
  10. /**
  11. */
  12. @SuppressWarnings("serial")
  13. public class DruidDataSource extends com.alibaba.druid.pool.DruidDataSource {
  14.  
  15. public PhysicalConnectionInfo createPhysicalConnection() throws SQLException {
  16. String url = this.getUrl();
  17. Properties connectProperties = getConnectProperties();
  18.  
  19. String user;
  20. if (getUserCallback() != null) {
  21. user = getUserCallback().getName();
  22. } else {
  23. user = getUsername();
  24. }
  25. //DES解密
  26. user = DESUtils.getDecryptString(user);
  27. String password = DESUtils.getDecryptString(getPassword());

  28. PasswordCallback passwordCallback = getPasswordCallback();
  29.  
  30. if (passwordCallback != null) {
  31. if (passwordCallback instanceof DruidPasswordCallback) {
  32. DruidPasswordCallback druidPasswordCallback = (DruidPasswordCallback) passwordCallback;
  33.  
  34. druidPasswordCallback.setUrl(url);
  35. druidPasswordCallback.setProperties(connectProperties);
  36. }
  37.  
  38. char[] chars = passwordCallback.getPassword();
  39. if (chars != null) {
  40. password = new String(chars);
  41. }
  42. }
  43.  
  44. Properties physicalConnectProperties = new Properties();
  45. if (connectProperties != null) {
  46. physicalConnectProperties.putAll(connectProperties);
  47. }
  48.  
  49. if (user != null && user.length() != 0) {
  50. physicalConnectProperties.put("user", user);
  51. }
  52.  
  53. if (password != null && password.length() != 0) {
  54. physicalConnectProperties.put("password", password);
  55. }
  56.  
  57. Connection conn;
  58.  
  59. long connectStartNanos = System.nanoTime();
  60. long connectedNanos, initedNanos, validatedNanos;
  61. try {
  62. conn = createPhysicalConnection(url, physicalConnectProperties);
  63. connectedNanos = System.nanoTime();
  64.  
  65. if (conn == null) {
  66. throw new SQLException("connect error, url " + url + ", driverClass " + this.driverClass);
  67. }
  68.  
  69. initPhysicalConnection(conn);
  70. initedNanos = System.nanoTime();
  71.  
  72. validateConnection(conn);
  73. validatedNanos = System.nanoTime();
  74.  
  75. setCreateError(null);
  76. } catch (SQLException ex) {
  77. setCreateError(ex);
  78. throw ex;
  79. } catch (RuntimeException ex) {
  80. setCreateError(ex);
  81. throw ex;
  82. } catch (Error ex) {
  83. createErrorCount.incrementAndGet();
  84. throw ex;
  85. } finally {
  86. long nano = System.nanoTime() - connectStartNanos;
  87. createTimespan += nano;
  88. }
  89.  
  90. return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos);
  91. }
  92. }

修改spring-content.xml文件的数据库连接数配置

  1. #修改之前
  2. <!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> -->
  3.  
  4. #修改之后
  5. <bean id="dataSource"class="com.thinkgem.jeesite.common.encrypt.DruidDataSource"
  6. init-method="init" destroy-method="close">
  7. <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
  8. <property name="driverClassName" value="${jdbc.driver}" />
  9. <!-- 基本属性 urluserpassword -->
  10. <property name="url" value="${jdbc.url}" />
  11. <property name="username" value="${jdbc.username}" />
  12. <property name="password" value="${jdbc.password}" />
  13.  
  14. </bean>

至此,数据库密文配置连接就完成了!

SSM实现mysql数据库账号密码加密连接的更多相关文章

  1. MySQL修改账号密码方法大全

    前言: 在日常使用数据库的过程中,难免会遇到需要修改账号密码的情景,比如密码太简单需要修改.密码过期需要修改.忘记密码需要修改等.本篇文章将会介绍需要修改密码的场景及修改密码的几种方式. 1.忘记 r ...

  2. SQL Server数据库账号密码变更后导致vCenter Server无法访问数据库

    SQL Server数据库账号密码变更后导致vCenter Server无法访问数据库 1.1状况描述: 若SQL Server数据库的账号(这里以sa为例)密码发生了变更,那么连接数据的客户端vCe ...

  3. mysql数据库忘记密码时如何修改(二)

    第一步:找到mysql数据库的my.ini配置文件,在[mysqld]下面添加一行代码:skip-grant-tables 第二步:运行services.msc进入服务管理界面,重启mysql服务. ...

  4. 修改MySQL数据库的密码

    通过MySQL命令行,可以修改MySQL数据库的密码,下面就为您详细介绍该MySQL命令行,如果您感兴趣的话,不妨一看. 格式:mysql -u用户名 -p旧密码 password 新密码 1.给ro ...

  5. 【转】mysql数据库中实现内连接、左连接、右连接

    [转]mysql数据库中实现内连接.左连接.右连接 内连接:把两个表中数据对应的数据查出来 外连接:以某个表为基础把对应数据查出来 首先创建数据库中的表,数据库代码如下: /* Navicat MyS ...

  6. 一键强制修改任意Mysql数据库的密码,修改任意环境Mysql数据库。

    本文采用我软件里面的内置改密功能,可以一键强制修改Mysql数据库的密码, 在修改过程中,会强制干掉Mysql主程序,修改完成后重新启动Mysql就可以了. 首先讲解如何一键强制修改PHPWAMP自身 ...

  7. mysql数据库忘记密码时如何修改(一)

    方法/步骤 打开mysql.exe和mysqld.exe所在的文件夹,复制路径地址 打开cmd命令提示符,进入上一步mysql.exe所在的文件夹. 输入命令  mysqld --skip-grant ...

  8. Mysql数据库忘记密码找回方法

    Mysql数据库忘记密码找回 a 停止mysql服务 /etc/init.d/mysql stop b 使用--skip-grant-tables启动mysql,忽略授权登录验证 mysqld_saf ...

  9. mysql数据库的安装和连接测试并给root用户赋密码

    一.mysql数据库的安装 Windows下MySQL的配置 以 MySQL 5.1 免安装版为例, 下载 mysql-noinstall-5.1.69-win32.zip ( 官方下载页: http ...

随机推荐

  1. 【Java Web开发学习】跨域请求

    [Java Web开发学习]跨域请求 ================================================= 1.使用jsonp ===================== ...

  2. 通过url返回的状态来抢注好的用户名

    之前在注册很多网站时都想取一个好的用户名,但是不知道那些被注册了没有,通常时一个一个测试,但是很慢当时就想过这个思路,由于懒并没有去搞 主要思路就是:很多网站的用户主页的Url都存在用户名,替换为自己 ...

  3. Linux查看文本的第20~30行

    一.模拟环境 [root@WT ~]# seq >/data/test.txt [root@WT ~]# xargs -n </data/test.txt 二.实现命令 方法一(head+ ...

  4. CentOS搭建yum源及EPEL仓库

    一.CentOS搭建yum源 1.备份配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backu ...

  5. Java堆的结构是什么样子的?什么是堆中的永久代(Perm Gen space)?

    JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存.它在JVM启动的时候被创建.对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收. 堆内存是由存活和死亡的对象组成的.存活的对象是应 ...

  6. linus 命令

    系统信息 arch 显示机器的处理器架构uname -m 显示机器的处理器架构uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI) h ...

  7. 数据库学习笔记day01+day02

    --表示系统时间select sysdate from dual --表是关系型数据库的基本结构--表是二维的,由行和列组成--行称为记录,列称为字段 --创建第一张表create table hw( ...

  8. 拥抱微服务,CODING 即将上线单项目多仓库功能

    随着数字化时代的全面到来,越来越多的企业开始尝试物联网.人工智能等新兴技术,用以加快自身的转型速度并积极开拓新的市场.互联网的兴起让各个行业的业务场景.用户行为.交互方式等都发生了巨大的变化.线上业务 ...

  9. <计算机系统结构中的8个伟大思想>

    摘自<计算机组成与设计>戴维帕森 ——面向摩尔定律的设计 ——使用抽象简化设计 ——加速大概率事件 ——通过并行提高性能 ——通过流水线提高性能 ——存储器层次 ——通过冗余提高可靠性

  10. 用python重新定义【2019十大网络流行语】

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:朱小五 PS:如有需要Python学习资料的小伙伴可以加点击下方链接 ...