- KDFDecryptedDataSourceFactory.java 파일 생성하여 소스내 적당한 util 폴더안에 넣어준다.
package mydomain.util.encrypt; // 패키지명 수정
import java.security.MessageDigest;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class KDFDecryptedDataSourceFactory extends BasicDataSourceFactory {
private final String key = "dfkjlajf902jklf"; // 암호화 키 설정
private final String symmAlg = "AES";
public static String randomIv(int len) {
StringBuffer strBuffer = new StringBuffer();
String iv = null, ivS = null;
Random rd = new Random();
for (int i = 0; i < len; i++) {
if (iv == null || iv.length() < len) {
ivS = Integer.toHexString(rd.nextInt());
iv = strBuffer.append(ivS).toString();
}
if (iv.length() > len) {
iv = iv.substring(0, len);
break;
}
if (iv.length() == len)
break;
}
return iv;
}
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
if (obj instanceof Reference) {
setUsername((Reference) obj);
setPassword((Reference) obj);
setUrl((Reference) obj);
}
return super.getObjectInstance(obj, name, nameCtx, environment);
}
private void setUrl(Reference ref) throws Exception {
findDecryptAndReplace("url", ref);
}
private void setUsername(Reference ref) throws Exception {
findDecryptAndReplace("username", ref);
}
private void setPassword(Reference ref) throws Exception {
findDecryptAndReplace("password", ref);
}
private void findDecryptAndReplace(String refType, Reference ref) throws Exception {
int idx = find(refType, ref);
String decrypted = decrypt(ref.get(idx).getContent().toString());
replace(idx, refType, decrypted, ref);
}
private void replace(int idx, String refType, String newValue, Reference ref) throws Exception {
ref.remove(idx);
ref.add(idx, new StringRefAddr(refType, newValue));
}
private int find(String addrType, Reference ref) throws Exception {
Enumeration enu = ref.getAll();
for (int i = 0; enu.hasMoreElements(); i++) {
RefAddr addr = (RefAddr) enu.nextElement();
if (addr.getType().compareTo(addrType) == 0)
return i;
}
throw new Exception("The \"" + addrType + "\" name/value pair was not found"
+ " in the Reference object. The reference Object is" + " " + ref.toString());
}
private String decrypt(String ciphertext) throws Exception {
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes());
byte[] hashVal = md.digest();
byte[] key = new byte[16];
System.arraycopy(hashVal, 0, key, 0, 16);
byte[] iv = new byte[16];
System.arraycopy(hashVal, 4, iv, 0, 16);
String encAlg = (symmAlg + "/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance(encAlg);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, symmAlg), new IvParameterSpec(iv));
String decryptedVal = new String(cipher.doFinal(Hex.decodeHex(ciphertext.toCharArray())));
return decryptedVal;
}
}
- 암호화된 url, username, password 복호화를 해본다.
package test.encrypt;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class KDFEncrypted {
public static void main(String[] args) {
String key = "dfkjlajf902jklf";
String url = "jdbc:mysql://127.0.0.1:3306/mydb?characterEncoding=UTF-8";
String username = "root";
String password= "root123";
try {
System.out.println("########### Encrypt ############");
byte[] enc_url = encrypt("AES", key.getBytes(), url.getBytes());
byte[] enc_username = encrypt("AES", key.getBytes(), username.getBytes());
byte[] enc_password = encrypt("AES", key.getBytes(), password.getBytes());
String hex_url = new String(Hex.encodeHex(enc_url));
String hex_username = new String(Hex.encodeHex(enc_username));
String hex_password = new String(Hex.encodeHex(enc_password));
System.out.println("enc_hex_url : " + hex_url);
System.out.println("enc_hex_username : " + hex_username);
System.out.println("enc_hex_password : " + hex_password);
} catch (Exception e){
e.printStackTrace();
}
}
public static byte[] encrypt(String symmAlg, byte[] passwd, byte[] tbeData) throws Exception {
byte[] encData = null;
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-256");
md.update(passwd);
byte[] hashVal = md.digest();
byte[] key = new byte[16];
System.arraycopy(hashVal, 0, key, 0, 16);
byte[] iv = new byte[16];
System.arraycopy(hashVal, 4, iv, 0, 16);
String encAlg = (symmAlg + "/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance(encAlg);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, symmAlg), new IvParameterSpec(iv));
encData = cipher.doFinal(tbeData);
return encData;
}
}
- DB url, username, password 값의 암호화된 String을 구한다. (테스트)
package sbbms.encrypt;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class KDFDecryptedTest{
private final static String key = "dfkjlajf902jklf";
private final static String symmAlg = "AES";
public static void main(String[] args) {
String key = "dfkjlajf902jklf";
String url = "54515aeac48aeac48aec481a38de7735e1f531eds5fes54515aeac48aeac48aec481a38de7735e1f531eds5fes";
String username = "a7e80ba13e818a3177e7731c156011a19f";
String password= "c8e0c3e8bba7731c156011a731c156e818";
try {
System.out.println("url : " + decrypt(url));
System.out.println("username : " + decrypt(username));
System.out.println("password : " + decrypt(password));
} catch (Exception e){
e.printStackTrace();
}
}
static String decrypt(String ciphertext) throws Exception {
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes());
byte[] hashVal = md.digest();
byte[] key = new byte[16];
System.arraycopy(hashVal, 0, key, 0, 16);
byte[] iv = new byte[16];
System.arraycopy(hashVal, 4, iv, 0, 16);
String encAlg = (symmAlg + "/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance(encAlg);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, symmAlg), new IvParameterSpec(iv));
String decryptedVal = new String(cipher.doFinal(Hex.decodeHex(ciphertext.toCharArray())));
return decryptedVal;
}
}
- server.xml에 factory, url, username, password 부분을 등록해 준다.
<Resource name="jdbc/mydb"
global="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
factory="mydomain.util.KDFDecryptedDataSourceFactory"
url="54515aeac48aeac48aec481a38de7735e1f531eds5fes"
username="a7e80ba13e818a3177e7731c156011a19f"
password="c8e0c3e8bba7731c156011a731c156e818"
maxActive="20"
maxIdle="20"
minIdle="5"
maxWait="3000"
validationQuery="SELECT 1"
validationInterval="30000"
/>
[출처]
'Infra Structure > WAS' 카테고리의 다른 글
[Tomcat] Windows setenv.bat 파일 활용하기 (0) | 2022.10.23 |
---|---|
war 파일 실행하기 (java -jar jenkins.war --httpPort=9090) (0) | 2022.07.24 |
[Tomcat] Redis를 통한 Session 관리 (0) | 2022.05.31 |
[Tomcat] properies 변수값 입력 (0) | 2022.03.04 |
[jBoss]배포 오류 (0) | 2021.10.13 |