首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 配置数据库用户名密码加密

Spring 配置数据库用户名密码加密

作者头像
汤高
发布2019-05-26 14:25:33
2.3K0
发布2019-05-26 14:25:33
举报
文章被收录于专栏:积累沉淀积累沉淀积累沉淀

Spring 配置数据库用户名密码加密

传统形式配置数据库用户名密码

对于一般的spring框架,经常要用到数据源配置,如果是用xml配置的话,一般都是如下形式

数据库用户名密码密文配置实现

现在的需求是不能在配置文件里明文配置数据库用户名和密码

新增密文属性文件

class目录新增jdbc.properties配置文件,里面配置数据库用户名和密码的密文

修改spring数据库配置为占位符

修改spring数据库配置,如下

引入密文配置文件jdbc.properties

并在spring文件开头中加入如下配置,引入jdbc.properties文件

<bean id="propertyConfigurer"
		  class="com.ai.common.util.EncrypPropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:jdbc.properties</value>
			</list>
		</property>
</bean>

自定义spring属性占位符处理类

EncrypPropertyPlaceholderConfigurer为自定义的,实现spring读取配置文件中的占位符,并且解析,注入解密后的数据库用户名和密码

public class EncrypPropertyPlaceholderConfigurer extends
        PropertyPlaceholderConfigurer {
    private Logger log= Logger.getLogger(EncrypPropertyPlaceholderConfigurer.class);

    @Override
    protected void processProperties(
            ConfigurableListableBeanFactory beanFactoryToProcess,
            Properties props) throws BeansException {
        String username = props.getProperty("jdbc.username");
        if (username != null) {// 将加密的username解密后塞到props
            String user = SymmetricEncoder.AESDncode(username);
            props.setProperty("jdbc.username", SymmetricEncoder.AESDncode(username));
        }
        String password = props.getProperty("jdbc.password");
        if (username != null) {
            props.setProperty("jdbc.password",
                    SymmetricEncoder.AESDncode(password));
        }
        super.processProperties(beanFactoryToProcess, props);
    }

    public static void main(String[] args) {
        String user="7Z3ekkmGFkOFjfpkNvg4cA==";
        System.out.println(AESCoderUtils.AESDncode(user));

    }

}

自定义AES加密解密算法

加密解密工具类

/**
 * <p>description:</p>
 *
 * @author tanggao
 * @version 1.0
 * @date 2018/10/18
 */
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/*
 * AES对称加密和解密
 */
public class SymmetricEncoder {
    /*
     * 加密
     * 1.构造密钥生成器
     * 2.根据ecnodeRules规则初始化密钥生成器
     * 3.产生密钥
     * 4.创建和初始化密码器
     * 5.内容加密
     * 6.返回字符串
     */
    public static String AESEncode(String content){
        try {
            // 初始化算法,设置成“SHA1PRNG”是为了防止在linux环境下随机生成算法
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed("xxx".getBytes("utf-8"));
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            keygen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();

            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");

            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte [] byte_encode=content.getBytes("utf-8");
            //9.根据密码器的初始化方式--加密:将数据加密
            byte [] byte_AES=cipher.doFinal(byte_encode);
            //10.将加密后的数据转换为字符串
            //这里用Base64Encoder中会找不到包
            //解决办法:
            //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
            String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
            //11.将字符串返回
            return AES_encode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //如果有错就返加nulll
        return null;
    }
    /*
     * 解密
     * 解密过程:
     * 1.同加密1-4步
     * 2.将加密后的字符串反纺成byte[]数组
     * 3.将加密内容解密
     */
    public static String AESDncode(String content){
        try {
            // 初始化算法,设置成“SHA1PRNG”是为了防止在linux环境下随机生成算法
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed("xxx".getBytes("utf-8"));

            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            keygen.init(128,secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //8.将加密并编码后的内容解码成字节数组
            byte [] byte_content= new BASE64Decoder().decodeBuffer(content);
            /*
             * 解密
             */
            byte [] byte_decode=cipher.doFinal(byte_content);
            String AES_decode=new String(byte_decode,"utf-8");
            return AES_decode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        //如果有错就返加nulll
        return null;
    }

    public static void main(String[] args) throws Exception {

        if(args.length!=1){
            throw  new Exception("请输入需要加密的内容!");
        }
        String user=args[0];

        String encrpt = AESEncode(user);
        System.out.println("加密后的密文为:"+encrpt);

        System.out.println(AESDncode(encrpt));
    }

}

使用

ApplicationContext  context = new ClassPathXmlApplicationContext(xmlpath);

注意:必须使用 ClassPathXmlApplicationContext,不能使用

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(xmlpath));

XmlBeanFactory 这种方式不支持

ClassPathXmlApplicationContext为启动加载即实bean,XmlBeanFactory 为延迟实例化bean,如果原先是用的XmlBeanFactory ,而现在改为ClassPathXmlApplicationContext后因为启动加载bean报错,就在beans中加入

或者在每个bean中加入

在beans中加入的default-lazy-init="true" 为全局设置,在bean中加入的lazy-init="true"为单个设置 ,单个设置优先局部

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年10月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring 配置数据库用户名密码加密
    • 传统形式配置数据库用户名密码
      • 数据库用户名密码密文配置实现
        • 新增密文属性文件
        • 修改spring数据库配置为占位符
        • 引入密文配置文件jdbc.properties
        • 自定义spring属性占位符处理类
        • 自定义AES加密解密算法
        • 使用
    相关产品与服务
    数据库
    云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档