1.加密算法
package cn.sh.ideal.encryption;
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;
/**
* @FileName: SymmetricEncoder
* @Author Steven
* @Date: 2020/8/31
*/
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
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
//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 (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;
}
}
2.数据库配置文件:datasource.properties
#测试数据库加密信息
jdbc-driver=oracle.jdbc.driver.OracleDriver
jdbc-url=jdbc:oracle:thin:@xx.xx.xx.xx:1521:snbst1
jdbc-user=cxjh3AWAFmPmsCdKYyoiPQ==
jdbc-password=JhDsPPKPIKlJJJtDMJa9Ug==
jdbc-url=jdbc:oracle:thin:@10.173.32.151:1521:snbst1
jdbc-user=h53HW7f3z7gAG1qFcSJqZQ==
jdbc-password=XZRhnL0hqtC4fkHvypOIvg==
3.扫描配置文件解析propertie:EncryptPropertyPlaceholderConfigurer.java
package cn.sh.ideal.encryption;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import java.util.Properties;
/**
* @FileName: EncryptPropertyPlaceholderConfigurer
* @Author Steven
* @Date: 2020/8/31
*/
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Logger log = Logger.getLogger(EncryptPropertyPlaceholderConfigurer.class);
@Override
protected void processProperties(
ConfigurableListableBeanFactory beanFactoryToProcess,
Properties props) throws BeansException {
// 将加密的username解密后塞到props
String userName1 = props.getProperty("jdbc-user");
if (userName1 != null) {
props.setProperty("jdbc-user", SymmetricEncoder.AESDncode(userName1));
}
String password1 = props.getProperty("jdbc-password");
if (password1 != null) {
props.setProperty("jdbc-password", SymmetricEncoder.AESDncode(password1));
}
String userName2 = props.getProperty("jdbc-user1");
if (userName2 != null) {
props.setProperty("jdbc-user1", SymmetricEncoder.AESDncode(userName2));
}
String password2 = props.getProperty("jdbc-password1");
if (password1 != null) {
props.setProperty("jdbc-password1", SymmetricEncoder.AESDncode(password2));
}
super.processProperties(beanFactoryToProcess, props);
}
}
4.base-config.xml
<!--1.将bean注入spring容器中-->
<bean id="propertyConfigurer" class="cn.sh.ideal.encryption.EncryptPropertyPlaceholderConfigurer">
<property name="locations">
<list> <value>classpath:cn/sh/ideal/encryption/jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc-driver}"/>
<property name="url" value="${jdbc-url}"/>
<property name="username" value="${jdbc-user}"/>
<property name="password" value="${jdbc-password}"/>
</bean>