diff --git a/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java b/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java index d118539..213cc3a 100644 --- a/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java +++ b/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java @@ -61,9 +61,7 @@ public class ApiAdapterController implements HttpAdapterServiceKey { // /api/v1/public/getUserInfo.svc apiUri = StringUtils.removeStart(apiUri, servletRequest.getContextPath()); apiUri = StringUtils.removeEnd(apiUri, "/"); -// TODO: 샘플 주석 작업 완료 후 제거 요망 -// String salt = servletRequest.getHeader("salt"); -// ElinkTransactionContext.setSeedSalt(salt); + //** jwhong TSEAIHS04의 api full path와 비교하여 adapter를 가져온다 String methodAndUri = servletRequest.getMethod() + "|" + apiUri; HttpDynamicInAdapterUri adptUri = null; 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 1f7be85..14acfa9 100644 --- a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java +++ b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java @@ -51,6 +51,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import org.springframework.security.oauth2.provider.ClientDetails; import com.nimbusds.jwt.SignedJWT; +import com.eactive.eai.common.context.ElinkTransactionContext; @Service @@ -68,6 +69,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { private static final String FILE_GROUP_NAME = "image-file"; private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH"; public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong + private boolean encryptResponseApply; // inbound에 대한 응답 암호화 여부 flag public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp, AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception { int traceLevel = 0; @@ -124,8 +126,11 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { transactionProp.put(INBOUND_TOKEN, inboundToken); transactionProp.put(ENCRYPT_AES256_IV, httpProp.getProperty(ENCRYPT_AES256_IV, "")); //jwhong transactionProp.put(ENCRYPT_AES256_KEY, httpProp.getProperty(ENCRYPT_AES256_KEY, "")); //jwhong + + // SEED 컬럼암호하 시 Key로 사용함 + String seedkey = getHeaders(request).getOrDefault("x-obp-partnercode", "").toString(); + ElinkTransactionContext.setSeedKey(seedkey); - try { traceLevel = Integer.parseInt(traceLevelTemp); } catch (Exception e) { @@ -317,29 +322,10 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { result = mapper.writeValueAsString(rootNode); } } - - // KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다. - //result = doPostEncryption(result, transactionProp); // jwhong Encrypt - // ASYNC 인 경우 광주은행은 RETURN 해 주는 값들이 수정되어야 한다. JWHONG - /* - if ("ASYN".equals(syncAsyncType) && MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName)) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode rootNode = (ObjectNode) mapper.readTree(result); - JsonNode headerGroup = rootNode.get(headerGroupName); - if(headerGroup != null) { - for(Iterator it = headerGroup.fieldNames(); it.hasNext();) { - String name = it.next(); - String value = headerGroup.get(name).asText(); - response.addHeader(name, value); - } - rootNode.remove(headerGroupName); - result = mapper.writeValueAsString(rootNode); - } - } - */ - - // KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다. - //result = doPostEncryption(result, transactionProp); // jwhong Encrypt + + // KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다. + encryptResponseApply = StringUtils.equalsIgnoreCase(httpProp.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); + result = doPostEncryption(result, transactionProp, request); // jwhong Encrypt return result; } @@ -382,7 +368,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { decryptedMessage = doInboundPreDecrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); if (decryptedMessage == null) { - throw new Exception("[HttpClient5AdapterServiceRest] Decrypt Error : Invalid encrypted message"); + throw new Exception("[ApiAdapterService] Decrypt Error : Invalid encrypted message"); } @@ -393,19 +379,26 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { // jwhong encrypt - private String doPostEncryption(String eaiBody, Properties transactionProp) { + private String doPostEncryption(String eaiBody, Properties transactionProp, HttpServletRequest request) throws Exception { + + if ( !encryptResponseApply) { + return eaiBody; + } + 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, ""); + String inboundToken = ""; String secretAES256Iv = transactionProp.getProperty("ENCRYPT_AES256_IV"); String secretAES256Key = transactionProp.getProperty("ENCRYPT_AES256_KEY"); - - + if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님 return eaiBody; } + + inboundToken = JwtTokenExtractor(request); + xElinkClientId = JwtClientIdExtractor(inboundToken); // token에서 client id를 추출함 // 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함 // ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함 @@ -421,12 +414,16 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { } } - byte[] decryptedMessage = null; - decryptedMessage = doInboundPostEncrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); + String encryptedMessage = null; + encryptedMessage = doInboundPostEncrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); - String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 ); - return resultMessage; - //return new String(decryptedMessage, StandardCharsets.UTF_8 ); + if (encryptedMessage == null) { + throw new Exception("[ApiAdapterService] Encrypt Error : Invalid PlainText message"); + } + + return encryptedMessage; + //String resultMessage = new String(encryptedMessage, StandardCharsets.UTF_8 ); + //return resultMessage; } @@ -466,7 +463,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); if (eaiStringBody == null) { - throw new Exception("[HttpClient5AdapterServiceRest] Cannot decrypt Error : input is plain text"); + throw new Exception("[ApiAdapterService] Cannot decrypt Error : input is plain text"); } //test source @@ -568,28 +565,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { String decryptedJsonKey = ""; String decryptedBodyMessage = ""; - switch (decryptAlgorithm) { - case "AES128": - case "AES128-TOSS": - decryptedJsonKey = "preScreeningRequest"; - break; - case "AES128-TOGETHER": - decryptedJsonKey = "obpTxData"; - break; - case "AES256": - decryptedJsonKey = "preScreeningRequest"; - break; - case "AES256-KAKAO": - decryptedJsonKey = "encrypted_data"; - break; - case "AES256-TOSS": - decryptedJsonKey = "encryptedData"; - break; - case "AES256GCM": - break; - default: - break; - } + decryptedJsonKey = getJsonKey(decryptAlgorithm); try { JSONParser parser = new JSONParser(); @@ -603,74 +579,95 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { return decryptedBodyMessage; } - - private byte[] doInboundPostEncrypt(String eaiStringBody, String encryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) { - - byte[] encryptedMessage = null; - //String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); - - //test source - logger.debug("Base64 문자열: " + eaiStringBody); - logger.debug("Base64 문자열 길이: " + eaiStringBody.length()); - logger.debug("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + + private String getJsonKey(String Algorithm) { - // Base64 디코딩 테스트 - try { - byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - logger.debug("디코딩 성공, 길이: " + decoded.length); - } catch (IllegalArgumentException e) { - logger.debug("Base64 디코딩 실패: " + e.getMessage()); - } - // end test source + String jsonKey = ""; + + switch (Algorithm) { + case "AES128": + case "AES128-TOSS": + jsonKey = "preScreeningRequest"; + break; + case "AES128-TOGETHER": + jsonKey = "obpTxData"; + break; + case "AES256": + jsonKey = "preScreeningRequest"; + break; + case "AES256-KAKAO": + jsonKey = "encrypted_data"; + break; + case "AES256-TOSS": + jsonKey = "encryptedData"; + break; + case "AES256-NICEON": + jsonKey = "enc_data"; + break; + case "AES256GCM": + break; + default: + break; + } + return jsonKey; + } + private String doInboundPostEncrypt(String eaiStringBody, String encryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) { + + //byte[] encryptedMessage = null; + String encryptedStrMessage = null; + String encryptedJsonKey = ""; + + encryptedJsonKey = getJsonKey(encryptAlgorithm); + switch (encryptAlgorithm) { case "AES128": case "AES128-TOSS": try { String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? - String decryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); } break; case "AES128-TOGETHER": try { String key128 = clientSecretKey.substring(44,60); //togetherEncoder 경우는 substring(44,60) 이네?? - String decryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage()); } break; case "AES256": try { String key = clientSecretKey.substring(10,42); - String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, key); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, key); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); } break; case "AES256-KAKAO": try { - String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); } break; case "AES256-TOSS": try { - String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); } break; @@ -680,8 +677,8 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { AES256GCMCipher cipher = new AES256GCMCipher(key); byte[] aad = "metadata".getBytes(); - String decryptedStrMessage = cipher.encrypt(eaiStringBody , aad); - encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + encryptedStrMessage = cipher.encrypt(eaiStringBody , aad); + //encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); @@ -690,7 +687,8 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { break; default: try { - encryptedMessage = eaiStringBody.getBytes(); + encryptedStrMessage = eaiStringBody; + //encryptedMessage = eaiStringBody.getBytes(); } catch (Exception e) { e.printStackTrace(); logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); @@ -698,7 +696,12 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { break; } - return encryptedMessage; + Map map = new HashMap<>(); + map.put(encryptedJsonKey, encryptedStrMessage); + JSONObject json = new JSONObject(); + json.putAll(map); + return json.toJSONString(); + //return encryptedMessage; }