From bf0f77838fec2803ce58be35cfd8563dc5d0d8be Mon Sep 17 00:00:00 2001 From: jaewohong Date: Mon, 13 Oct 2025 16:24:57 +0900 Subject: [PATCH] =?UTF-8?q?KJBank=20=EC=95=94=ED=98=B8=ED=99=94=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/service/ApiAdapterService.java | 140 +++++++++++++++++- 1 file changed, 136 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java index f527741..77b80b4 100644 --- a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java +++ b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java @@ -48,7 +48,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import org.springframework.security.oauth2.provider.ClientDetails; - @Service public class ApiAdapterService extends HttpAdapterServiceSupport { static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); @@ -62,7 +61,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { private static final String JSON_FIELD_NAME = "json-body"; private static final String FILE_GROUP_NAME = "image-file"; private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH"; - + public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp, AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception { int traceLevel = 0; @@ -83,7 +82,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { String paramValue = null; String adptMsgType = null; - + transactionProp.put(INBOUND_METHOD, request.getMethod()); transactionProp.put(INBOUND_URI, request.getRequestURI()); transactionProp.put(INBOUND_HEADER, getHeaders(request)); @@ -93,7 +92,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); transactionProp.put(INBOUND_EXTURI, extUrl); } else { - transactionProp.put(INBOUND_EXTURI, getExtUri(request)); + transactionProp.put(INBOUND_EXTURI, getExtUri(request)); } transactionProp.put(INBOUND_CLIENT_IP, getClientIp(request)); // Client IP 추가 transactionProp.put(Processor.REQUEST_ACTION, adapterVO.getAdapterGroupVO().getRefClass()); @@ -105,6 +104,13 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { transactionProp.put(ENC_PATHS, httpProp.getProperty(ENC_PATHS, "")); + transactionProp.put(ENCRYPT_ALGORITHM, httpProp.getProperty(ENCRYPT_ALGORITHM, "")); //jwhong + transactionProp.put(HEADER_NAME_CLIENT_ID, getHeaders(request).get(HEADER_NAME_CLIENT_ID)); // jwhong + transactionProp.put(ENCRYPT_BASE_TYPE, httpProp.getProperty(ENCRYPT_BASE_TYPE, "")); //jwhong + //transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN)); // jwhong + transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN) != null ? getHeaders(request).get(INBOUND_TOKEN) : ""); //jwhong , null 이면 default로 "" put + + try { traceLevel = Integer.parseInt(traceLevelTemp); } catch (Exception e) { @@ -210,6 +216,9 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { if (paramValue == null) { // parameter가 없는 경우때문에 처리 paramValue = ""; + } + else { // jwhong decrypt + paramValue = doPreDecryption(paramValue, transactionProp); } if ("Y".equals(urlDecodeYn) && isParameterType) { @@ -292,6 +301,129 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { return result; } + + + // jwhong encrypt + + private String doPreDecryption(String eaiBody, Properties transactionProp) { + String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, ""); + String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong + String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE); + String inboundToken = transactionProp.getProperty(INBOUND_TOKEN, ""); + + if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님 + return eaiBody; + } + + // 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함 + // ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함 + String clientSecret = ""; + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId); + + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } + } + + byte[] decryptedMessage = null; + decryptedMessage = doInboundPreDecrypt(eaiBody, decryptAlgorithm,clientSecret); + + String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 ); + return resultMessage; + //return new String(decryptedMessage, StandardCharsets.UTF_8 ); + } + + + private byte[] convertObjectToBytes(Object obj) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + return bos.toByteArray(); + } + + private byte[] convertObjectToBase64Bytes(Object obj) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + oos.close(); + + // 직렬화된 byte[] → Base64 문자열 → 다시 byte[]로 변환 + String base64String = Base64.getEncoder().encodeToString(bos.toByteArray()); + return base64String.getBytes(StandardCharsets.UTF_8); + } + + public static Object convertBytesToObject(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bis)) { + return ois.readObject(); + } + } + + + private byte[] doInboundPreDecrypt(String eaiStringBody, 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 "AES128": + + String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? + try { + //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": + String key = clientSecretKey.substring(10,42); + try { + 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; + default: + try { + //decryptedMessage = Arrays.copyOf(eaiBody, eaiBody.length); + decryptedMessage = eaiStringBody.getBytes(); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); + } + break; + } + + return decryptedMessage; + } + + // jwhong until here private Map assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName,