spring*.xml配置文件明文加密

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

1.数据库配置文件加密

原xml配置


        .....

加密实现过程

思路:继承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;
    }

}

修改后配置文件


        .....

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配置


加密思路:由于项目使用的时候是获取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, passWord.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)));
    }

}

Original: https://www.cnblogs.com/GeoffA/p/14252849.html
Author: 昊狼
Title: spring*.xml配置文件明文加密

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/586466/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MyBatis复杂映射开发之多对多查询

    多对多查询的模型 用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用。 多对多查询的需求:查询所有用户的同时查询出该用户对应的所有角色。 @startuml !th…

    Java 2023年6月5日
    0105
  • 一文带你看懂Java中的Lock锁底层AQS到底是如何实现的

    先获取锁的状态,判断锁的状态是不是等于0,等于0说明没人加锁,可以尝试去加,如果被加锁了,就会走else if,else if会判断加锁的线程是不是当前线程,是的话就给state …

    Java 2023年6月16日
    0101
  • 一、mybatis入门案例

    今天学习了mybatis框架,简单记录一下mybatis第一个入门案例,目标是使用Mybatis作为持久层框架,执行查询数据的SQL语句并且获取结果集 基本步骤: 物理建模 逻辑建…

    Java 2023年6月16日
    0105
  • 6.Hystrix入门

    Hystrix两种命令模式 HystrixCommand和HystrixObservableCommand Command会以隔离的形式完成run方法调用 ObservableCo…

    Java 2023年6月8日
    088
  • 做仿牛客社区项目的搭建环境中,下载的合集包里面少个AOP

    在引入一批包的时候,即在start.spring.io网址中下载时,因为2022年start.spring.io更新后确实搜不到aop了,但是其他的包是可以的。这个工具的作用,就是…

    Java 2023年6月5日
    097
  • java AWT弹球游戏

    java AWT弹球游戏 1 package io.guanghe; 2 3 import javax.swing.*; 4 import java.awt.*; 5 import…

    Java 2023年5月29日
    076
  • C语言实现顺序栈、单链栈、双向链栈

    #define Maxlength 8 /** * 数据结构类型:顺序栈 * 插入方法:尾插法 * 是否有头节点:否 * 说明:在主函数直接定义一个结构体节点,取地址作形参,避免使…

    Java 2023年6月9日
    070
  • win10下计算文件哈希值的方法

    cmd下使用certutil命令 使用方法: certutil -hashfile FILE_NAME ALGORITHM_NAME 支持的加密算法包括:MD2,MD4,MD5,S…

    Java 2023年6月9日
    0111
  • 第二周总结-Spring学习

    java;gutter:true;</p> <h2>Spring_day01</h2> <p><strong>今日目标&…

    Java 2023年6月7日
    089
  • SpringBoot在Tomcat部署war包

    启动类配置 继承SpringBootServletInitializer @SpringBootApplication public class TestApplication e…

    Java 2023年6月15日
    097
  • Spring 5 源码解析- 事务原理分析-6

    事务配置 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http:/…

    Java 2023年6月6日
    077
  • 白嫖CSDN付费资源方法

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年5月29日
    070
  • 使用 Azure 静态 Web 应用服务免费部署 Hexo 博客

    一.前言 最近在折腾 Hexo 博客,试了一下 Azure 的静态 Web 应用服务,发现特别适合静态文档类型的网站,而且具有 免费额度,支持绑定域名。本文只是以 Hexo 作为示…

    Java 2023年6月8日
    0136
  • Java基础之运算符

    Java基础之运算符 Java基础之运算符 – 1.1 运算符介绍 1.1.1 运算符介绍 1.2 算术运算符 1.2.1 介绍 1.2.2 算术运算符一览表 1.2….

    Java 2023年6月15日
    062
  • Mybatis 原始dao CRUD方法

    用到的相关jar包及所用版本如下: 其中的Mybatis可以到github.com的网站下载 <project xmlns="http://maven.apache…

    Java 2023年5月30日
    077
  • IDEA快捷键(windows)

    一、官方文档 IntelliJIDEA_ReferenceCard.pdf (jetbrains.com) 二、文档翻译 2.1 记住这些快捷键 REMEMBER THESE SH…

    Java 2023年6月8日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球