diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 86f64ec..0ddd235 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -84,13 +84,12 @@ import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; -//import com.kjbank.encrypt.exchange.crypto.AES256Cipher; -//import com.kjbank.encrypt.exchange.crypto.AESCipher; -//import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; +import com.kjbank.encrypt.exchange.crypto.AES256Cipher; +import com.kjbank.encrypt.exchange.crypto.AESCipher; +import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.eactive.eai.authserver.service.OAuth2Manager; - /** * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 * 기능을 제공한다.
@@ -311,7 +310,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case PUT: case POST: // assignPostBody(dataObject, contentType, vo.getEncode(), method); - assignPostBody(dataContent, contentType, vo.getEncode(), method); + //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName()); break; default: break; @@ -359,6 +359,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp try { byte[] responseMessage = null; + byte[] responseMessageOri = null; Header[] responseHeaders; if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { @@ -392,6 +393,11 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp context.setAttribute(HttpClientAdapterServiceKey.LOG_PROCESS_NO, logProcessNo); } + // encrypt algorithm type 추출 from adapter property jwhong + Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); // jwhong + try { if (logger.isDebug()) { logger.debug("[method getName]" + method.getMethod()); @@ -402,8 +408,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method, context)) { status = response.getCode(); - responseMessage = EntityUtils.toByteArray(response.getEntity()); - responseHeaders = response.getHeaders(); + //responseMessage = EntityUtils.toByteArray(response.getEntity()); + // 역기서 responseMessage를 decryption 해야 하나 by jwhong + + responseMessageOri = EntityUtils.toByteArray(response.getEntity()); + System.out.println("responseMessageOri 바이트 배열 길이: " + responseMessageOri.length); + + responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName()); // jwhong + // 여기까지 + + responseHeaders = response.getHeaders(); if (logger.isDebug()) { logger.debug("[received status]" + status); @@ -512,6 +526,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method)) { status = response.getCode(); responseMessage = EntityUtils.toByteArray(response.getEntity()); + // 여기서도 decryption 해야 할듯 하나.. by jwhong if (logger.isDebug()) { logger.debug("[received status]" + status); @@ -722,7 +737,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName) { if (eaiBody == null) { return; } @@ -732,6 +747,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp List params = new ArrayList<>(); JSONObject jsonObject = (JSONObject) eaiBody; for (Object key : jsonObject.keySet()) { + //String encryptedValue = encrypt((String) jsonObject.get(key)); // encrypt by jwhong + //params.add(new BasicNameValuePair((String) key, encryptedValue )); params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); } @@ -741,13 +758,243 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); + String eaiBodyMessage = doOutboundPreFilter(eaiBody,adapterName); // jwhong + StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 - StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); + //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); // 요청에 본문 추가 method.setEntity(entity); } } + + private String doOutboundPreFilter(Object eaiBody, String adapterName) { + + Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. + // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. + // 여기에 NICE-auth 뭔지 파악하여 logic 추가해야 한다. + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + String clientSecret = ""; + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } + + // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. + + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret); + return responseMessage; + + } + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey) { + + String encryptedMessage = ""; + + switch (encryptAlgorithm) { + case "AES": + encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong + break; + case "AES128-TOSS": + try { + String key = clientSecretKey.substring(22,38); + encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key = clientSecretKey.substring(44,60); + encryptedMessage = AESCipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); + } + break; + case "AES256": + //AES256Cipher aes256Cipher = new AES256Cipher(); + try { + //String cleintSecretKey="BxnZ4wpIrTSw8fAkMuF3lYIGZySl1vl47jrErPpGWbAH7uUBeVsJ77njNUrnkAdHJ5fKbNqbiNIE6qCAJ8KfxYJMmbZZrsXCwNMUFooRUcsyRfcDd80h9v490UO4YoQB"; + String key = clientSecretKey.substring(10,42); + //String key = "0123456789abcdefghij0123456789ab"; + //encryptedMessage= aes256Cipher.encrypt(eaiBody.toString(), key); + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); + + encryptedMessage = cipher.encrypt(eaiBody.toString(), aad); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + default: + encryptedMessage = eaiBody.toString(); + break; + } + return encryptedMessage; + } + + + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName) { + + Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong + String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + String clientSecret = ""; + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } + + // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. + byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret); + return resPostMessage; + } + + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey) { + + byte[] decryptedMessage = null; + String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + + //test source + System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); + System.out.println("Base64 문자열: " + eaiStringBody); + System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); + System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + + // Base64 디코딩 테스트 + try { + byte[] decoded = Base64.getDecoder().decode(eaiStringBody); + System.out.println("디코딩 성공, 길이: " + decoded.length); + } catch (IllegalArgumentException e) { + System.out.println("Base64 디코딩 실패: " + e.getMessage()); + } + // end test source + + switch (decryptAlgorithm) { + case "AES": + decryptedMessage = decrypt(eaiBody); // encrypt by jwhong + break; + case "AES128-TOSS": + try { + String key128 = clientSecretKey.substring(22,38); + //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key128 = clientSecretKey.substring(44,60); + //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES256": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); + String decryptedStrMessage = cipher.decrypt(eaiStringBody, aad); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + default: + try { + decryptedMessage = Arrays.copyOf(eaiBody, eaiBody.length); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); + } + break; + } + + return decryptedMessage; + } + + + // by jwhong + private String encrypt(String plainText) { + try { + SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(encrypted); + } catch (Exception e) { + // 예외 로그 출력 또는 사용자 정의 처리 + e.printStackTrace(); + return null; // 또는 에러 메시지 반환 + } + } + + + public static byte[] decrypt(byte[] encryptedBytes) { + try { + // byte[] --> Base64 문자열로 변환 + String encryptedText = new String(encryptedBytes, StandardCharsets.UTF_8).trim(); + // 암호화에 사용한 키와 동일한 키 사용 + SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(), "AES"); + + // 암호화와 동일한 알고리즘 설정 + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, key); + + // Base64로 인코딩된 문자열을 디코딩 + byte[] decodedBytes = Base64.getDecoder().decode(encryptedText); + + // 복호화 수행 + byte[] decryptedBytes = cipher.doFinal(decodedBytes); + + // UTF-8 문자열로 변환하여 반환 + //return new String(decryptedBytes, StandardCharsets.UTF_8); + //복호화된 바이트 배열 반환 + return decryptedBytes; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + private HashMap getParameters(Object message) throws Exception { diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java index 4bc9084..f83d8f3 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -72,6 +72,10 @@ public interface HttpAdapterServiceKey { static final String ENC_PATHS = "ENC_PATHS"; + static final String ENCRYPT_ALGORITHM = "ENCRYPT_ALGORITHM"; //jwhong + static final String INBOUND_TOKEN = "authorization"; // jwhong + static final String ENCRYPT_BASE_TYPE = "ENCRYPT_BASE_TYPE"; // jwhong + //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; } diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java index 86612cd..ae79af9 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -30,6 +30,7 @@ import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.message.ServiceMessage; import com.eactive.eai.common.monitor.StatMonitorLogVO; import com.eactive.eai.common.property.PropManager; + import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.server.EAIServerVO; import com.eactive.eai.common.server.loader.EAIServerLoader; @@ -470,8 +471,22 @@ public class EAILogDAO { } } else { biz = bizMsgStr; - } - + } + + // jwhong safeDB 암호화 + /* + if ("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN())) { + try { + biz = EncryptSafeDb(bizMsgStr); + } catch (Exception e) { + logger.error("EAIFileLogger] bizMsgStr encryption Error - " + e.getMessage()); + } + } else { + biz = bizMsgStr; + } + */ + // jwhong safeDB end + // 임시코드 시작 String logType = PropManager.getInstance().getProperty("BIZ_LOG_TYPE"); if (!StringUtils.isBlank(logType)) { @@ -839,5 +854,13 @@ public class EAILogDAO { } return false; } + + + private String EncryptSafeDb(String msg) { + PropManager propManager = PropManager.getInstance(); + String safeDbPath = propManager.getProperty("SafeDB","safedb.path"); + return "this is a message"; + } + } diff --git a/src/main/java/com/eactive/eai/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java index 5f55115..c775498 100644 --- a/src/main/java/com/eactive/eai/common/util/JMSSender.java +++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java @@ -79,8 +79,11 @@ public class JMSSender { Iterator it = prop.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); - String value = prop.getProperty(key); - msg.setStringProperty(key, value); + Object getObjectVal = prop.get(key); // by jwhong 2025-09 + String value = getObjectVal != null ? getObjectVal.toString() : ""; // by jwhong + msg.setStringProperty(key, value); + //String value = prop.getProperty(key); + //msg.setStringProperty(key, value); } } qsender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); diff --git a/src/main/java/com/eactive/eai/env/ElinkConfig.java b/src/main/java/com/eactive/eai/env/ElinkConfig.java index e8d88b5..b3024f4 100644 --- a/src/main/java/com/eactive/eai/env/ElinkConfig.java +++ b/src/main/java/com/eactive/eai/env/ElinkConfig.java @@ -20,7 +20,8 @@ import com.eactive.eai.common.util.ContainerUtil; @PropertySource("/WEB-INF/properties/env.common.properties") public class ElinkConfig implements ConfigKeys { // message handling options - private static boolean useInternalQueue = true; + //private static boolean useInternalQueue = true; + private static boolean useInternalQueue = false; // weblogic JMS jwhong private static boolean useCacheTopic = true; private static boolean useCacheStore = true;