spring*.xml配置文件明文加密的实现

网友投稿 1032 2023-02-21

spring*.xml配置文件明文加密的实现

spring*.xml配置文件明文加密的实现

说明:客户要求spring*.xml中Oracle/Redis/MongoDB的IP、端口、用户名、密码不能明文存放,接到需求的我,很无奈,但是还是的硬着头皮搞

系统架构:spring+mvc(Oracle是用jdbc自己封装的接口)

1.数据库配置文件加密

原xml配置

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:aop="http://springframework.org/schema/aop"

xmlns:tx="http://springframework.org/schema/tx"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context.xsd"

default-autowire="byType">

.....

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:aop="http://springframework.org/schema/aop"

xmlns:tx="http://springframework.org/schema/tx"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context.xsd"

default-autowire="byType">

.....

加密实现过程

思路:继承DruidDataSource,在初始化set值的时候进行解密

/**

* 数据库连接解密

* @author: Geoff

* @create: 2020-12-30 16:46

**/

public class DataBaseXml extends DruidDataSource {

/**

* Log4j logger

*/

private final static Logger lg = LoggerFactory.getLogger(DataBaseXml.class);

@Override

public String getUrl() {

return this.jdbcUrl;

}

@Override

public void setUrl(String jdbcUrl) {

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("数据库【jdbcUrl】解密初始化加载...");

try {

jdbcUrl = Encryption.decrypt(jdbcUrl, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("数据库【jdbcUrl】密文解密失败...");

e.printStackTrace();

}

}

this.jdbcUrl = jdbcUrl;

}

@Override

public String getUsername() {

return this.username;

}

@Override

public void setUsername(String username) {

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("数据库【username】解密初始化加载...");

try {

username = Encryption.decrypt(username, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("数据库【username】密文解密失败...");

e.printStackTrace();

}

}

this.username = username;

}

@Override

public String getPassword() {

return this.password;

}

@Override

public void setPassword(String password) {

if(GEOFF.DATA_BASE_IS_ENCRYPTION){

lg.info("数据库【password】解密初始化加载...");

try {

password = Encryption.decrypt(password, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("数据库【password】密文解密失败...");

e.printStackTrace();

}

}

this.password = password;

}

}

修改后配置文件

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:aop="http://springframework.org/schema/aop"

xmlns:tx="http://springframework.org/schema/tx"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context.xsd"

default-autowire="byType">

.....

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:aop="http://springframework.org/schema/aop"

xmlns:tx="http://springframework.org/schema/tx"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="

http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/aop http://springframework.org/schema/aop/spring-aop.xsd

http://springframework.org/schema/tx http://springframework.org/schema/tx/spring-tx.xsd

http://springframework.org/schema/context http://springframework.org/schema/context/spring-context.xsd"

default-autowire="byType">

.....

2.Redis配置文件加密

原配置文件

加密实现思路:由于JedisPool使用构造函数来创建,所以继承JedisPool后,在调用JedisPool构造函数的时候,调用static解密方法进行解密

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import redis.clients.jedis.*;

/**

* redis数据库用户名密码解密

* @author: Geoff

* @create: 2020-12-30 17:20

**/

public class JedisPoolXml extends JedisPool{

/**

* Log4j logger

*/

private final static Logger lg = LoggerFactory.getLogger(JedisPoolXml.class);

public JedisPoolXml(GenericObjectPoolConfig poolConfig, String host, String port, String timeout, String password) {

super(poolConfig,decryptHost(host),decryptPort(port),decryptTimeout(timeout),decryptPassword(password), 0, (String)null);

}

private JedisPoolXml(GenericObjectPoolConfig poolConfig, String host, String port,String timeout, String password, String database){

super(poolConfig,decryptHost(host),decryptPort(port),decryptTimeout(timeout),decryptPassword(password),decryptDatabase(database));

}

private static String decryptHost(String host){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("Redis【host】解密初始化加载...");

try {

host = Encryption.decrypt(host, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("Redis【host】密文解密失败...");

e.printStackTrace();

}

}

return host;

}

private static int decryptPort(String port){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("Redis【port】解密初始化加载...");

try {

port = Encryption.decrypt(port, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("Redis【port】密文解密失败...");

e.printStackTrace();

}

}

return Integer.parseInt(port);

}

private static int decryptTimeout(String timeout){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("Redis【timeout】解密初始化加载...");

try {

timeout = Encryption.decrypt(timeout, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("Redis【timeout】密文解密失败...");

e.printStackTrace();

}

}

return Integer.parseInt(timeout);

}

private static String decryptPassword(String password){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("Redis【password】解密初始化加载...");

try {

password = Encryption.decrypt(password, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("Redis【password】密文解密失败...");

e.printStackTrace();

}

}

return password;

}

private static int decryptDatabase(String database){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("Redis【database】解密初始化加载...");

try {

database = Encryption.decrypt(database, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("Redis【database】密文解密失败...");

e.printStackTrace();

}

}

return Integer.parseInt(database);

}

}

修改后xml

3.MongoDB配置文件加密(使用的是spring-data-mognodb框架)

原xml配置

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:mongo="http://springframework.org/schema/data/mongo"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/data/mongo http://springframework.org/schema/data/mongo/spring-mongo.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:mongo="http://springframework.org/schema/data/mongo"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/data/mongo http://springframework.org/schema/data/mongo/spring-mongo.xsd">

加密思路:由于项目使用的时候是获取bean的方式来获取MongoTemplate和mongoDbFactory的,尝试过各种方法来继承后加密,但是最后都不行,后面只能通过手动的方法进行初始化,并将对应MongoTemplate和mongoDbFactory注入到bean中

import com.mongodb.*;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;

import org.springframework.data.mongodb.core.convert.MappingMongoConverter;

import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import org.springframework.data.mongodb.gridfs.GridFsTemplate;

import java.util.ArrayList;

import java.util.List;

/**

* @author: Geoff

* @create: 2020-12-31 16:15

**/

@Configuration

public class MongoDBXml {

/**

* Log4j logger

*/

private final static Logger lg = LoggerFactory.getLogger(MongoDBXml.class);

private String host;

private Integer port;

private String userName;

private String passWord;

private String dataBase;

private SimpleMongoDbFactory mongoDbFactory = null;

private MappingMongoConverter converter = null;

public String getHost() {

return host;

}

public void setHost(String host) {

this.host = decryptHost(host);

}

public Integer getPort() {

return port;

}

public void setPort(String port) {

this.port = decryptPort(port);

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = decryptUserName(userName);

}

public String getPassWord() {

return passWord;

}

public void setPassWord(String passWord) {

this.passWord = decryptPassword(passWord);

}

public String getDataBase() {

return dataBase;

}

public void setDataBase(String dataBase) {

this.dataBase = decryptDatabase(dataBase);

}

private String decryptHost(String host){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("MongoDB【host】解密初始化加载...");

try {

host = Encryption.decrypt(host, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("MongoDB【host】密文解密失败...");

e.printStackTrace();

}

}

return host;

}

private int decryptPort(String port){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("MongoDB【port】解密初始化加载...");

try {

port = Encryption.decrypt(port, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("MongoDB【port】密文解密失败...");

e.printStackTrace();

}

}

return Integer.parseInt(port);

}

private String decryptUserName(String userName){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("MongoDB【userName】解密初始化加载...");

try {

userName = Encryption.decrypt(userName, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("MongoDB【userName】密文解密失败...");

e.printStackTrace();

}

}

return userName;

}

private String decryptPassword(String passWord){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("MongoDB【password】解密初始化加载...");

try {

passWord = Encryption.decrypt(passWord, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("MongoDB【password】密文解密失败...");

e.printStackTrace();

}

}

return passWord;

}

private String decryptDatabase(String dataBase){

if(GEOFF.DATA_BASE_IS_ENCRYPTION) {

lg.info("MongoDB【database】解密初始化加载...");

try {

dataBase = Encryption.decrypt(dataBase, GEOFF.DATA_BASE_ENCRYPTION_KEY);

} catch (Exception e) {

lg.error("MongoDB【database】密文解密失败...");

e.printStackTrace();

}

}

return dataBase;

}

public void init() {

MongoClientOptions.Builder build = new MongoClientOptions.Builder();

MongoClientOptions options = build.build();

try {

List addrs = new ArrayList();

ServerAddress serverAddress = new ServerAddress(host, port);

addrs.add(serverAddress);

MongoCredential credential = MongoCredential.createScramSha1Credential(userName, dataBase, parYWQFPbAUjssWord.toCharArray());

List credentials = new ArrayList();

credentials.add(credential);

MongoClient mongoClient = new MongoClient(addrs, credentials, options);

mongoDbFactory = new SimpleMongoDbFactory(mongoClient, dataBase);

DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);

MongoMappingContext mongoMappingContext = new MongoMappingContext();

converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);

lg.info(" mongodb客户端创建成功 ");

} catch (Exception e) {

lg.info(" mongodb客户端创建失败 ");

e.printStackTrace();

}

documentTemplate();

gridFsTemplate();

}

@Bean

public MongoTemplate documentTemplate() {

if (mongoDbFactory != null && converter != null) {

lg.info("MongoTemplate初始化成功......");

MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);

return mongoTemplate;

} else {

lg.error("MongoTemplate初始化失败......");

return null;

}

}

@Bean

public GridFsTemplate gridFsTemplate() {

if (mongoDbFactory != null && converter != null) {

lg.info("GridFsTemplate初始化成功......");

GridFsTemplate gridFsTemplate = new GridFsTemplate(mongoDbFactory, converter);

return gridFsTemplate;

} else {

lg.error("GridFsTemplate初始化失败......");

return null;

}

}

public void destroy(){

try {

this.mongoDbFactory.destroy();

} catch (Exception e) {

e.printStackTrace();

}

}

}

修改后配置文件

4.最后附上对应的加解密类

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.DESKeySpec;

import java.security.Key;

import java.security.SecureRandom;

/**

* 加密生成token的方法

*

* @author: Geoff

* @create: 2020-12-30 17:03

**/

public class Encryption {

// 算法名称

public static final String KEY_ALGORITHM = "DES";

// 算法名称/加密模式/填充方式

// DES共有四种工作模式-->>ECB:电子密码本模式、CBC:加密分组链接模式、CFB:加密反馈模式、OFB:输出反馈模式

public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";

/**

* 生成密钥key对象

*

* @param

* @return 密钥对象

* @throws Exception

*/

private static SecretKey keyGenerator(String keyStr) throws Exception {

byte[] input = HexString2Bytes(keyStr);

DESKeySpec desKey = new DESKeySpec(input);

// 创建一个密匙工厂,然后用它把DESKeySpec转换成

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);

SecretKey securekey = keyFactory.generateSecret(desKey);

return securekey;

}

/**

* 从十六进制字符串到字节数组转换

*/

public static byte[] HexString2Bytes(String hexStr) {

byte[] keyBytes = hexStr.getBytes();

if (keyBytes.length == 16) {

byte[] tmpKey = new byte[24];

System.arraycopy(keyBytes, 0, tmpKey, 0, 16);

System.arraycopy(keyBytes, 0, tmpKey, 16, 8);

keyBytes = tmpKey;

}

return keyBytes;

}

/**

* 加密数据

*

* @param data 待加密数据

* @param key 密钥

* @return 加密后的数据

*/

public static String encrypt(String data, String key) throws Exception {

Key deskey = keyGenerator(key);

// 实例化Cipher对象,它用于完成实际的加密操作

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

SecureRandom random = new SecureRandom();

// 初始化Cipher对象,设置为加密模式

cipher.init(Cipher.ENCRYPT_MODE, deskey, random);

byte[] results = cipher.doFinal(data.getBytes());

// 执行加密操作。加密后的结果通常都会用Base64编码进行传输

return Base64.encodeBase64String(results);

}

/**

* 解密数据

*

* @param data 待解密数据

* @param key 密钥

* @return 解密后的数据

*/

public static String decrypt(String data, String key) throws Exception {

Key deskey = keyGenerator(key);

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

// 初始化Cipher对象,设置为解密模式

cipher.init(Cipher.DECRYPT_MODE, deskey);

// 执行解密操作

return new String(cipher.doFinal(Base64.decodeBase64(data)));

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:移动应用程序设计与开发(移动应用程序设计与开发就业方向)
下一篇:vuejs(vuejs和vue的区别)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~