druid數據庫密碼加密很簡單,它提供了一個解密回調,我們只需要具體實現就可以了,加解密邏輯可以自己實現。
大體思路:
1、預先根據公鑰(自定義)生成加密密碼,配置在yml文件中
2、實現加解密算法。
3、編寫自己的回調類,實現自己的回調邏輯,並配置到yml中
一、配置文件(公鑰、密碼接口回調類)
yml文件:
spring:
datasource:
# 公鑰
publicKey: GOURD-HXNLYW-201314
type: com.alibaba.druid.pool.DruidDataSource
master:
url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: hWm9HtDn605aupyXTuuA5Q==
# 配置 connection-properties,啓用加密,配置公鑰。
connection-properties: config.decrypt=true;publicKey=${spring.datasource.publicKey};password=${spring.datasource.master.password}
passwordCallbackClassName: com.gourd.index.config.DbPasswordCallback
slave:
url: jdbc:mysql://47.103.5.190:3306/gourd?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: hWm9HtDn605aupyXTuuA5Q==
# 配置 connection-properties,啓用加密,配置公鑰。
connection-properties: config.decrypt=true;publicKey=${spring.datasource.publicKey};password=${spring.datasource.slave.password}
passwordCallbackClassName: com.gourd.index.config.DbPasswordCallback
druid:
initial-size: 5
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
二、加解密工具類(自定義):
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* AesHope工具類
*
* @author: gourd
*
**/
@Slf4j
public class AesHopeUtil {
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/***
* AES加密
* @param password
* @param content
* @return
* @throws Exception
*/
public static String encrypt(String password, String content){
//創建密碼器
Cipher cipher = null;
try {
cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
byte[] bytes = content.getBytes("utf-8");
//初始化密碼器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(password));
//加密
byte[] bytes1 = cipher.doFinal(bytes);
//通過BASE64轉碼返回
return Base64.encodeBase64String(bytes1);
} catch (NoSuchAlgorithmException e) {
log.error("{}",e);
} catch (NoSuchPaddingException e) {
log.error("{}",e);
} catch (BadPaddingException e) {
log.error("{}",e);
} catch (UnsupportedEncodingException e) {
log.error("{}",e);
} catch (IllegalBlockSizeException e) {
log.error("{}",e);
} catch (InvalidKeyException e) {
log.error("{}",e);
}
return null;
}
/***
* AES解密
* @param password
* @param content
* @return
* @throws Exception
*/
public static String decryt(String password, String content) {
Cipher cipher = null;
try {
cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//使用密鑰初始化解密
cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(password));
byte[] bytes = cipher.doFinal(Base64.decodeBase64(content));
return new String(bytes, "utf-8");
} catch (NoSuchAlgorithmException e) {
log.error("{}",e);
} catch (NoSuchPaddingException e) {
log.error("{}",e);
} catch (BadPaddingException e) {
log.error("{}",e);
} catch (UnsupportedEncodingException e) {
log.error("{}",e);
} catch (IllegalBlockSizeException e) {
log.error("{}",e);
} catch (InvalidKeyException e) {
log.error("{}",e);
}
return null;
}
/***
* 生成加密密鑰
* @param password
* @return
* @throws NoSuchAlgorithmException
*/
private static SecretKeySpec getSecretKeySpec(final String password) {
//返回密鑰生成器對象
KeyGenerator keyGenerator = null;
try {
keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
//設置AES密鑰長度
keyGenerator.init(128, secureRandom);
//生成一個密鑰
SecretKey secretKey = keyGenerator.generateKey();
//轉換爲AES密鑰
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
log.error("{}",e);
}
return null;
}
}
三、回調類,實現自己的回調邏輯
import com.alibaba.druid.util.DruidPasswordCallback;
import com.gourd.common.utils.AesHopeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Properties;
/**
* 數據庫回調密碼解密
*
* @author gourd
*
*/
@Component
@Slf4j
public class DbPasswordCallback extends DruidPasswordCallback {
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
String password = properties.getProperty("password");
String publicKey = properties.getProperty("publicKey");
if (StringUtils.isNotEmpty(password)) {
try {
//所以這裏的代碼是將密碼進行解密
String sourcePassword = AesHopeUtil.decryt(publicKey, password);
setPassword(sourcePassword.toCharArray());
} catch (Exception e) {
setPassword(password.toCharArray());
}
}
}
/**
* 生成加密後的密碼,放到yml中
* @param args
*/
public static void main(String[] args) {
// 生成加密後的密碼,放到yml中
String password = "gourd123";
String pwd = AesHopeUtil.encrypt("GOURD-HXNLYW-201314",password);
System.out.println(pwd);
String source = AesHopeUtil.decryt("GOURD-HXNLYW-201314",pwd);
System.out.println(source);
}
}
到此就結束了。
Druid多數據源配置請移步:https://blog.csdn.net/HXNLYW/article/details/90519757