SSM实现mysql数据库账号密码密文登录功能
作者:zsq_fengchen 发布时间:2024-01-28 16:52:30
标签:SSM,mysql,密文,登录
引言
咱们公司从事的是信息安全涉密应用的一些项目研发一共有分为三步,相比较于一般公司和一般的项目,对于信息安全要求更加严格,领导要求数据量和用户的用户名及密码信息都必需是要密文配置和存储的,这就涉及到jdbc.properties文件中的数据库的用户名和密码也是一样的,需要配置问密文,在连接的时候再加载解密为明文进行数据库的连接操作,以下就是实现过程,一共有分为三步。
一、创建DESUtil类
提供自定义密钥,加密解密的方法。
package com.hzdy.DCAD.common.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
/**
* Created by Wongy on 2019/8/8.
*/
public class DESUtil {
private static Key key;
//自己的密钥
private static String KEY_STR = "mykey";
static {
try {
KeyGenerator generator = KeyGenerator.getInstance("DES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(KEY_STR.getBytes());
generator.init(secureRandom);
key = generator.generateKey();
generator = null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 对字符串进行加密,返回BASE64的加密字符串
*
* @param str
* @return
* @see [类、类#方法、类#成员]
*/
public static String getEncryptString(String str) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
byte[] strBytes = str.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptStrBytes = cipher.doFinal(strBytes);
return base64Encoder.encode(encryptStrBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 对BASE64加密字符串进行解密
*
*/
public static String getDecryptString(String str) {
BASE64Decoder base64Decoder = new BASE64Decoder();
try {
byte[] strBytes = base64Decoder.decodeBuffer(str);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptStrBytes = cipher.doFinal(strBytes);
return new String(encryptStrBytes, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String name = "dbuser";
String password = "waction2016";
String encryname = getEncryptString(name);
String encrypassword = getEncryptString(password);
System.out.println("encryname : " + encryname);
System.out.println("encrypassword : " + encrypassword);
System.out.println("name : " + getDecryptString(encryname));
System.out.println("password : " + getDecryptString(encrypassword));
}
}
二、 创建EncryptPropertyPlaceholderConfigurer类
建立与配置文件的关联。
package com.hzdy.DCAD.common.util;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
//属性需与配置文件的KEY保持一直
private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};
@Override
protected String convertProperty(String propertyName, String propertyValue) {
//如果在加密属性名单中发现该属性
if (isEncryptProp(propertyName)) {
String decryptValue = DESUtil.getDecryptString(propertyValue);
System.out.println(decryptValue);
return decryptValue;
} else {
return propertyValue;
}
}
private boolean isEncryptProp(String propertyName) {
for (String encryptName : encryptPropNames) {
if (encryptName.equals(propertyName)) {
return true;
}
}
return false;
}
}
三、 修改配置文件 jdbc.properties
#加密配置之前
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.user=root
#jdbc.password=root
#jdbc.url=jdbc:mysql://localhost:3306/bookstore
#加密配置之后
jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=Ov4j7fKiCzY=
jdbc.password=Ov4j7fKiCzY=
jdbc.url=jdbc:mysql://localhost:3306/bookstore
四、 修改spring-content.xml配置文件
将spring-context中的
<context:property-placeholder location="classpath:.properties" />
修改为
<bean class="com.hzdy.DCAD.common.util.EncryptPropertyPlaceholderConfigurer"p:locations="classpath:*.properties"/>
//注意只能存在一个读取配置文件的bean,否则系统只会读取最前面的
注意:如果发现配置密文的username
和password
可以加载并解密成功,但是最后连接的时候还是以密文连接并报错,这可能涉及到内存预加载的问题,项目一启动,程序会加密密文的用户名和密码,就算最后解密成功了,最后连接数据库读取的却还是密文,这时候我们可以自己重写连接池的方法,让spring-content.xml
加载重写的连接池方法,并在连接的时候再提前进行解密。
package com.thinkgem.jeesite.common.encrypt;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.security.auth.callback.PasswordCallback;
import com.alibaba.druid.util.DruidPasswordCallback;
/**
*/
@SuppressWarnings("serial")
public class DruidDataSource extends com.alibaba.druid.pool.DruidDataSource {
public PhysicalConnectionInfo createPhysicalConnection() throws SQLException {
String url = this.getUrl();
Properties connectProperties = getConnectProperties();
String user;
if (getUserCallback() != null) {
user = getUserCallback().getName();
} else {
user = getUsername();
}
//DES解密
user = DESUtils.getDecryptString(user);
String password = DESUtils.getDecryptString(getPassword());
PasswordCallback passwordCallback = getPasswordCallback();
if (passwordCallback != null) {
if (passwordCallback instanceof DruidPasswordCallback) {
DruidPasswordCallback druidPasswordCallback = (DruidPasswordCallback) passwordCallback;
druidPasswordCallback.setUrl(url);
druidPasswordCallback.setProperties(connectProperties);
}
char[] chars = passwordCallback.getPassword();
if (chars != null) {
password = new String(chars);
}
}
Properties physicalConnectProperties = new Properties();
if (connectProperties != null) {
physicalConnectProperties.putAll(connectProperties);
}
if (user != null && user.length() != 0) {
physicalConnectProperties.put("user", user);
}
if (password != null && password.length() != 0) {
physicalConnectProperties.put("password", password);
}
Connection conn;
long connectStartNanos = System.nanoTime();
long connectedNanos, initedNanos, validatedNanos;
try {
conn = createPhysicalConnection(url, physicalConnectProperties);
connectedNanos = System.nanoTime();
if (conn == null) {
throw new SQLException("connect error, url " + url + ", driverClass " + this.driverClass);
}
initPhysicalConnection(conn);
initedNanos = System.nanoTime();
validateConnection(conn);
validatedNanos = System.nanoTime();
setCreateError(null);
} catch (SQLException ex) {
setCreateError(ex);
throw ex;
} catch (RuntimeException ex) {
setCreateError(ex);
throw ex;
} catch (Error ex) {
createErrorCount.incrementAndGet();
throw ex;
} finally {
long nano = System.nanoTime() - connectStartNanos;
createTimespan += nano;
}
return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos);
}
}
修改spring-content.xml文件的数据库连接数配置
#修改之前
<!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> -->
#修改之后
<bean id="dataSource"class="com.thinkgem.jeesite.common.encrypt.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
至此,数据库密文配置连接就完成了!
总结
以上所述是小编给大家介绍的SSM实现mysql数据库账号密码密文登录功能,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://www.cnblogs.com/zhaosq/archive/2019/08/09/11321157.html
0
投稿
猜你喜欢
- sql server的备份与恢复(查询分析器) 查询分析器: 命令: 1:备份数据库命令: backup database whdb1(要备
- lambda函数用法lambda非常重要的一个定义。lambda在【运行时】才绑定,【不是】在定义的时候绑定。下面这个列子:本意想:让X分别
- 将进程挂起(Suspend) 而非 阻塞(Block)如果用sleep() 进程将阻塞假设进程下有两个线程 那么这两个线程会继续运行要使进程
- 如果一个模型里包含了ManyToManyField,在admin后台可能会显示成object,例如解决方法:在定义这个类的时候,加多一个函数
- 1、安装coveragepip install coverage安装完成后,会在Python环境下的\Scripts下看到coverage.
- 变量名1、组成:数字、字母、下划线2、变量名要有意义3、多个单词则用下划线,如user_id4、python的变量名不要驼峰显示字符串:1、
- 本文实例讲述了Django框架静态文件处理、中间件、上传文件操作。分享给大家供大家参考,具体如下:Django静态文件处理、中间件、上传文件
- 基础知识-----黄金分割法960px宽度的网格设计的好处无需我多说了,下面主要是复习一下如何作图求出960px宽度下的黄金分割点1、首先沿
- 使用Python内置函数:bin()、oct()、int()、hex()可实现进制转换。 先看Python官方文档中对这几个内置函数的描述:
- 一段这样的JavaScript代码,猜猜结果如何?var i = 0, m =
- 最近,需要对日志文件进行实时数据处理。一、简单的实时文件处理(单一文件)假设我们要实时读取的日志的路径为: /data/mongodb/sh
- 不错,这个是一个文章详细页,没有左右两栏布局,不过这里我重点要讲的是合理的布局,在稍后的文章中我会详细的介绍浮动元素。好,回到刚才的话题,大
- 今天开始学习Python时发现Pycharm竟然过期了需要重新注册,穷苦学生没钱只能再找找百度了浪费了半天时间终于找到一个可以使用的了,支持
- 现在只有山东、北京、上海等发达地区有考Python的这个举动,其他地区暂时还没有。首先,Python类似于c++,Python是一种面向对象
- 前言:柱状图是一种使用矩形柱来表示数据分布的图表,可以横向排列,也可以纵向排列,它的高度或长度和他们所代表的值成正比关系。Matplotli
- 往期学习:python数据类型: python数据结构:数据类型.python的输入输出: python数据结构之输入输出及控制和异常.py
- numpy.linalg.norm函数的使用1、linalg = linear(线性)+ algebra(代数),norm则表示范数。首先需
- 本文实例讲述了php实现mysql事务处理的方法。分享给大家供大家参考。具体分析如下:要实现本功能的条件是环境 mysql 5.2 /php
- 这两天为用bottle+mongodb写的一个项目加上登录功能,无奈怎么都获取不到保存的cookie,文档给出让我们这样操作cookie的代
- Matlab常用的输出命令1、disp方法(1)方法(2)方法(3)需要注意:直接加数字不会显示数字,num2str()使数值转换为字符串类