linux服务器 spring 数据库配置加密

版权声明:本文为博主原创文章,未经博主允许不得转载。否则,吔屎伺候。 https://blog.csdn.net/guowujun321/article/details/79315328
在spring.xml配置properties文件时,可以通过
<!-- 指定数据源配置文件 -->
<context:property-placeholder location="classpath:*.properties" />

以通配符【*】匹配所有properties文件。

一般来说,打包好的项目要交付给运维时,都需要将数据库的用户名和密码加密,此时以通配符来匹配,倒行不通了,因为我们需自定义解密类。

首先跑个main方法或者@Test方法 把用户名和密码加密,替换jdbc.properties里的用户名和密码,如下:

username=n5ObTJEjFBNijYQ7vtR6Og==
password=30eG52KcqRVNlWy8lt0yLw==

这样还看得出来,我就呀屎。

别说你认不出来,就算是spring也认不出来,这TM什么jb配置。

所以,得帮spring一把,偷偷帮它解密,附在耳边告诉它:是这样,&%¥@#!@¥%*&……

-_-!!

改动spring.xml的配置方式,如果只有一个jdbc.properties需要加载,那直接配置

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

就可以了,如果还有其他properties配置文件要加载,那就再加上

<context:property-placeholder location="classpath:classpath:log4j.properties,classpath:redis.properties," ignore-unresolvable="true"/>

location里多个可以用逗号隔开,另外 ignore-unresolvable="true"必须加上。

至于DecryptPropertyPlaceholderConfigurer这个类,需要自己创建了,目的是为了解析jdbc配置的加密信息。

扫描二维码关注公众号,回复: 3540688 查看本文章
public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer{
    /** 
     * 重写父类方法,解密指定属性名对应的属性值 
     */  
    @Override  
    protected String convertProperty(String propertyName,String propertyValue){  
        if(isEncryptPropertyVal(propertyName)){  
            return DigestExampleUtil.getDecryptString(propertyValue);//调用解密方法  
        }else{  
            return propertyValue;  
        }  
    }  
    /** 
     * 判断属性是否需要解密
     * @param propertyName 
     * @return 
     */  
    private boolean isEncryptPropertyVal(String propertyName){  
        if(propertyName!=null && "username,password".contains(propertyName)){  
            return true;  
        }else{  
            return false;  
        }  
    }  
}
DigestExampleUtil类:
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class DigestExampleUtil {
    private static final String PASSWORD = "WTF";
    public static void main(String[] args) throws UnsupportedEncodingException {
        String content = "123456";  
        //加密  
        System.out.println("加密前:" + content);  
        byte[] encryptResult = encrypt(content);  
        String encryptResultStr = new String(Base64.encodeBase64(encryptResult));
        System.out.println(encryptResultStr);
        //解密  
        
        byte[] decryptFrom = Base64.decodeBase64(encryptResultStr); 
        byte[] decryptResult = decrypt(decryptFrom);  
        System.out.println("解密后:" + new String(decryptResult));  
    }
    
    public static String getDecryptString(String encryptResultStr) {
        String ym = "";
        try {
            byte[] decryptFrom = Base64.decodeBase64(encryptResultStr);  
            byte[] decryptResult = decrypt(decryptFrom);  
            ym = new String(decryptResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ym; 
    }
    
    
    public static byte[] encrypt(String content) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(PASSWORD.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return result; // 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static byte[] decrypt(byte[] content) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(PASSWORD.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(content);
            return result; // 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
用的是AES加密,dataSource 里的 配置依旧不变,如下:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>

到此就OK了.......

#2018年6月15日18:24:55 修改#

按上面的流程,在windows下是没问题的,但Linux下却不行。

原因:SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。(这句话我抄来的!!!)

那可咋整?

往死里整!

把上面的加密解密代码改改:

KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("OJBK" );
secureRandom.setSeed(PASSWORD.getBytes());     
kgen.init(128, secureRandom);
                      
//kgen.init(128, new SecureRandom(PASSWORD.getBytes()));  //← 注释了它   加上它们 ↑
SecretKey secretKey = kgen.generateKey();
如此才算大功告成,阿弥陀佛,端午安康!
 
 


猜你喜欢

转载自blog.csdn.net/guowujun321/article/details/79315328
今日推荐