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 a2b6a46..86a47aa 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 @@ -1,4 +1,4 @@ -package com.eactive.eai.adapter.http.client.impl; +package com.eactive.eai.adapter.http.client.impl; import java.io.IOException; import java.io.StringReader; @@ -87,7 +87,6 @@ import java.util.Base64; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.nimbusds.jwt.SignedJWT; -import com.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.kjbank.encrypt.exchange.crypto.ECDHESA256Cipher; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -106,7 +105,7 @@ import java.util.Set; * @see : HttpClientAdapterServiceFactory.java, * HttpClientAdapterServiceSupport.java * @since : - * + * */ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupport implements HttpClientAdapterServiceKey { @@ -118,9 +117,9 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String HTTP_STATUS = "HTTP_STATUS"; public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String AUTH_TOKEN = "AUTH_TOKEN"; - + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong - + private boolean useAdapterToken; private boolean encryptResponseApply; @@ -166,8 +165,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); - - //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 + + //Outbound 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); /** @@ -320,17 +319,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { - String niceToken = accessToken.getAccessToken(); - String clientId = JwtClientIdExtractor(niceToken); - long currentTime = System.currentTimeMillis(); - auth = niceToken + ":" + currentTime + ":" + clientId ; - auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); - - setNiceOnAuthHeaders(method, auth); - } else { + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + String niceToken = accessToken.getAccessToken(); + String clientId = JwtClientIdExtractor(niceToken); + long currentTime = System.currentTimeMillis(); + auth = niceToken + ":" + currentTime + ":" + clientId ; + auth = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8")); + + setNiceOnAuthHeaders(method, auth); + } else { setAuthHeaders(method, accessToken); // 원래 있던 logic - } + } if (logger.isDebug()) { @@ -342,8 +341,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if(!StringUtils.isBlank(authToken)) { setAuthHeaders(method, authToken); } - // 여기 까지 - + // 여기 까지 + configureHttpClient(requestConfigBuilder, vo, method); switch (HttpMethodType.getValue(rmethod)) { @@ -370,7 +369,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken); break; default: break; @@ -381,15 +380,15 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + method.getEntity() + "] "); } - // OAuth2AccessToken 원래 있던 위치 JWHONG + // OAuth2AccessToken 원래 있던 위치 JWHONG // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader); - + // KJBank API 추적정보를 Header에 제공. jwhong //assignRequestKJHeaders(method, prop, tempProp ); - + int status = -1; try { @@ -431,7 +430,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // encrypt algorithm type 추출 from adapter property jwhong Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - + try { if (logger.isDebug()) { logger.debug("[method getName]" + method.getMethod()); @@ -444,14 +443,14 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //responseMessage = EntityUtils.toByteArray(response.getEntity()); // 역기서 responseMessage를 decryption 해야 하나 by jwhong - + responseMessageOri = EntityUtils.toByteArray(response.getEntity()); logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessageOri.length); - - responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong + + responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 - - responseHeaders = response.getHeaders(); + + responseHeaders = response.getHeaders(); if (logger.isDebug()) { logger.debug("[received status]" + status); @@ -472,7 +471,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp * OAuth 토큰 응답 체크(Adapter properties로 설정) * 응답코드에 따라 유효한 토큰 확인(토큰 재발급 여부 확인) * API 서비스 마다 정책이 다름(보통 400대에서 체크하나 200에서도 체크할 수 있음) - * + * * TOKEN_ERROR_CODE_KEY: 응답 json error code key * __ex) $.dataHeader.resultCode * TOKEN_ERROR_CODE_VALUES: 토큰 재발급이 필요한 응답 error codes(ex: O0001,O0002,O0003) @@ -481,10 +480,10 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp * @formatter:on */ boolean needReissue = false; - + Properties responseHeaderProp = assignRelayDataToInbound(tempProp, responseHeaders); String responseString = new String(responseMessage, vo.getEncode()); - + Map map = new HashMap(); tempProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, responseHeaderProp); @@ -505,7 +504,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseString); // logger.error(errMsg); - + if (status >= 400 && status < 500) { if (useAdapterToken) { needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, @@ -516,7 +515,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp throw new Exception(errMsg); } } else { - + throw new Exception(errMsg); } } @@ -648,7 +647,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (responseHeaders == null || responseHeaders.length == 0) { return headerProp; } - + for (Header header : responseHeaders) { headerProp.put(header.getName(), header.getValue()); } @@ -658,7 +657,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp /** * 현재 1단계 레이아웃에만 적용되도록 구현됨. - * + * * @param method * @param responseMessage * @param headerGroupName @@ -670,7 +669,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ @SuppressWarnings("unchecked") private String assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, - String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { + String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { if (!MessageType.JSON.equals(messageType) || StringUtils.isBlank(headerGroupName) || StringUtils.isBlank(relayHeaderKeys)) { return new String(responseMessage, encode); @@ -716,40 +715,40 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } - - /* nice on 나이스 지키미 용으로 생성함 + + /* nice on 나이스 지키미 용으로 생성함 * jwhong 2015-11-04 */ private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { - method.setHeader("Authorization", - String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 - method.setHeader("ProductID", "2303345072"); + method.setHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, auth)); // 나이스지키미 format임 + method.setHeader("ProductID", "2303345072"); //method.setHeader("Authorization", // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } - /* nice clientid 추출을 위하여 추가한 내용임. jwhong - * - */ - private String JwtClientIdExtractor(String inboundToken) { + /* nice clientid 추출을 위하여 추가한 내용임. jwhong + * + */ + private String JwtClientIdExtractor(String inboundToken) { - String tokenClientId =""; - try { - SignedJWT signedJWT = SignedJWT.parse(inboundToken); - tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + String tokenClientId =""; + try { + SignedJWT signedJWT = SignedJWT.parse(inboundToken); + tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); } catch (Exception e) { logger.error(e.getMessage()); tokenClientId = ""; } - - logger.debug("[ NICE Token Client ID ]" + tokenClientId); - return tokenClientId; - } - + logger.debug("[ NICE Token Client ID ]" + tokenClientId); + return tokenClientId; + + } + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, - String encode) { + String encode) { if (responseMessage == null) { return false; } @@ -809,83 +808,68 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //weblogic 에서는 tempProp.get 이 property로 return 해어 아래처럼 수정함. ClassCastException 발생함. //Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); Properties inboundHeaders = null; - String authorization = ""; String authorization =""; try { Object headerObj = tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); - System.out.println("*** inboundheader Ojb:"+headerObj); if (headerObj instanceof Properties) { //tomcat inboundHeaders = (Properties) headerObj; - System.out.println("*** inboundHeaders tomcat:"+inboundHeaders); - for (String k : inboundHeaders.stringPropertyNames()) { - System.out.println("*** inboundheader k is:"+k); - if (k.equalsIgnoreCase("authorization")) { - authorization = inboundHeaders.getProperty(k); - break; - } - } for ( String k : inboundHeaders.stringPropertyNames()) { - if(k.equalsIgnoreCase("authorization")) { + if(k.equalsIgnoreCase("authorization")) { authorization = inboundHeaders.getProperty(k); break; } } } else if (headerObj instanceof String) { //weblogic String str = (String) headerObj; - System.out.println("*** inboundHeaders weblogic str:"+str); str = str.substring(1, str.length() - 1); - + // 2. key=value 쌍 분리 String[] entries = str.split(","); - + // map에 담기 Map map = new HashMap<>(); for (String entry : entries) { String[] kv = entry.split("=", 2); if (kv.length == 2) { - map.put( kv[0].trim(), kv[1].trim()); + map.put(kv[0].trim(), kv[1].trim()); } } - for (String k : map.keySet() ) { - if ( k.equalsIgnoreCase("authorization")) { + for (String k : map.keySet()) { + if (k.equalsIgnoreCase("authorization")) { authorization = map.get(k); break; } - } - } - } catch (Exception e) { - e.printStackTrace(); + } + } + } catch (Exception e) { + e.printStackTrace(); } - + String jwtToken = ""; - + if (authorization != null && authorization.startsWith("Bearer ")) { - jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 + jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출 } - - System.out.println("*** authorization is:"+authorization); - System.out.println("*** jwtToken is:"+jwtToken); - + /* 업체정보 */ - String clientId = JwtClientIdExtractor(jwtToken); - method.setHeader("clientId", clientId); - System.out.println("*** header clientID biz company code:"+clientId); - - /* APIM 거래추적자 */ - String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); - method.setHeader("traceId", uuid); - - /* GUID */ - String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); - method.setHeader("guid", guid); - - /* 최초요청시간 */ - String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); - method.setHeader("receivedTimestamp", receivedTimestamp); - - return jwtToken; + String clientId = JwtClientIdExtractor(jwtToken); + method.setHeader("clientId", clientId); + + /* APIM 거래추적자 */ + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, ""); + method.setHeader("traceId", uuid); + + /* GUID */ + String guid = tempProp.getProperty(TransactionContextKeys.GUID, ""); + method.setHeader("guid", guid); + + /* 최초요청시간 */ + String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, ""); + method.setHeader("receivedTimestamp", receivedTimestamp); + + return jwtToken; } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken) { if (eaiBody == null) { return; } @@ -896,7 +880,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp 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, encryptedValue )); params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); } @@ -907,7 +891,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp ContentType contentTypeObj = ContentType.create(contentType, charset); String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken); // jwhong - StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); + StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -915,153 +899,151 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setEntity(entity); } } - - // from here by jwhong + + // from here by jwhong private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth, String inboundToken) { - + 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"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - + String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + String certPath = properties.getProperty("ENCRYPT_CERT_PATH"); + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. // outbound 알림결과는 SecretKey, NICE-auth, Token을 사용한다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. // 여기에 NICE-auth logic 추가함 . String clientSecret = ""; - if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { - clientSecret = inboundToken; - } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. - // 업체가 우리 OAuth 를 사용하는 경우임 - clientSecret = clientDetail.getClientSecret(); - } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. - clientSecret = encryptClientId; - } - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { - clientSecret = niceAuth; - } - - // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 업체가 우리 OAuth 를 사용하는 경우임 + clientSecret = clientDetail.getClientSecret(); + } else { // 이경우는 우리 OAuth를 사용안하는 경우임, 업체에서 사용하는 secretkey를 사용한다. + clientSecret = encryptClientId; + } + } + + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(encryptAlgorithm)) { + clientSecret = niceAuth; + } + + // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key, certPath); logger.debug("outbound pre encrypte value is :"+responseMessage); return responseMessage; - + } private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key, String certPath ) { - + String encryptedMessage = ""; String encryptedJsonKey = ""; - + encryptedJsonKey = getJsonKey(encryptAlgorithm); - + switch (encryptAlgorithm) { - case "AES": - encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong - break; - case "AES128": - 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": - try { - String key = clientSecretKey.substring(10,42); - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-KAKAO": - try { - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-TOSS": - try { - encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-NICEON": - try { - String key = clientSecretKey.substring(10,42); - 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; - case "ECDHESA256": - try { - ECDHESA256Cipher cipher = new ECDHESA256Cipher(); + case "AES": + encryptedMessage = encrypt(eaiBody.toString()); // encrypt by jwhong + break; + case "AES128": + 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": + try { + String key = clientSecretKey.substring(10,42); + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + encryptedMessage = AES256Cipher.encrypt(eaiBody.toString(), encryptAES256Iv, encryptAES256Key); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + try { + String key = clientSecretKey.substring(10,42); + 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()); - System.out.println("Encrypted JWE: " + encryptedMessage); + encryptedMessage = cipher.encrypt(eaiBody.toString(), aad); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + case "ECDHESA256": + try { + ECDHESA256Cipher cipher = new ECDHESA256Cipher(); - String decrypted = cipher.decrypt(encryptedMessage); - System.out.println("Decrypted Payload: " + decrypted); - - //아래 인증서로 테스트 - ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); - encryptedMessage = cipherCert.encrypt(eaiBody.toString()); - - decrypted = cipherCert.decrypt(encryptedMessage); - - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); - } - break; - default: - encryptedMessage = eaiBody.toString(); - return encryptedMessage; + encryptedMessage = cipher.encrypt(eaiBody.toString()); + System.out.println("Encrypted JWE: " + encryptedMessage); + + String decrypted = cipher.decrypt(encryptedMessage); + System.out.println("Decrypted Payload: " + decrypted); + + //아래 인증서로 테스트 + ECDHESA256Cipher cipherCert = new ECDHESA256Cipher(certPath); + encryptedMessage = cipherCert.encrypt(eaiBody.toString()); + + decrypted = cipherCert.decrypt(encryptedMessage); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + default: + encryptedMessage = eaiBody.toString(); + return encryptedMessage; //break; } - + Map map = new HashMap<>(); map.put(encryptedJsonKey, encryptedMessage); JSONObject json = new JSONObject(); @@ -1069,84 +1051,52 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return json.toJSONString(); //return encryptedMessage; } - - + + private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { - + if ( !encryptResponseApply) { return eaiBody; } - return encryptedMessage; - //break; - } - - Map map = new HashMap<>(); - map.put(encryptedJsonKey, encryptedMessage); - JSONObject json = new JSONObject(); - json.putAll(map); - return json.toJSONString(); - //return encryptedMessage; - } - - - private byte[] doOutboundPostFilter(byte[] eaiBody, String decryptAlgorithm, String adapterName, OAuth2AccessTokenVO niceAccessToken ) { - - if ( !encryptResponseApply) { - return eaiBody; - } - + 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"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); - String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); - + //String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong + //String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + String encryptClientId = properties.getProperty("ENCRYPT_CLIENT_ID"); + String encryptAES256Iv = properties.getProperty("ENCRYPT_AES256_IV"); + String encryptAES256Key = properties.getProperty("ENCRYPT_AES256_KEY"); + // outbound encrypt 는 SecretKey 또는 NICE-auth 가 암호화 key로 사용된다. - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); - String clientSecret = ""; - if ( clientDetail != null ) { - clientSecret = clientDetail.getClientSecret(); - } else { - clientSecret = encryptClientId; - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { - clientSecret = niceAccessToken.getAccessToken(); - } - - byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); - } else { - clientSecret = encryptClientId; - } - - // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. - if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { - clientSecret = niceAccessToken.getAccessToken(); - } - + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); + String clientSecret = ""; + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } else { + clientSecret = encryptClientId; + } + + // Nice-auth , token 값을 substring 해서 사용한다. 나이스 지키미는 adapter token에서 추출된 token을 사용한다. + if (useAdapterToken && "AES256-NICEON".equals(decryptAlgorithm)) { + clientSecret = niceAccessToken.getAccessToken(); + } + byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); return resPostMessage; } - - private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key , String encryptAES256Iv, String encryptAES256Key ) { - + + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { + byte[] decryptedMessage = null; String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); - + try { eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); } catch (ParseException e) { logger.debug("[JSON 파싱 오류 발생 : ]" +e.getMessage()); return eaiBody; - } - - eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); - + } + //test source /* logger.debug("eaiBody 바이트 배열 길이: " + eaiBody.length); @@ -1157,246 +1107,196 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // Base64 디코딩 테스트 try { - byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - logger.debug("[디코딩 성공, 길이: ]" + decoded.length); + byte[] decoded = Base64.getDecoder().decode(eaiStringBody); + logger.debug("[디코딩 성공, 길이: ]" + decoded.length); } catch (IllegalArgumentException e) { logger.debug("[Base64 디코딩 실패: ]" + e.getMessage()); } - // end test source - + // end test source + switch (decryptAlgorithm) { - case "AES": - decryptedMessage = decrypt(eaiBody); // encrypt by jwhong - break; - case "AES128": - case "AES128-TOSS": - try { - String key128 = clientSecretKey.substring(22,38); - 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.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 "AES256-KAKAO": - try { - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-TOSS": - try { - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); - } - break; - case "AES256-NICEON": - 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; + case "AES": + decryptedMessage = decrypt(eaiBody); // encrypt by jwhong + break; + case "AES128": + case "AES128-TOSS": + try { + String key128 = clientSecretKey.substring(22,38); + 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.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 "AES256-KAKAO": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, encryptAES256Iv, encryptAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage()); + } + break; + case "AES256-NICEON": + 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; + + return decryptedMessage; } - - + + private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) throws ParseException { String decryptedJsonKey = ""; String decryptedBodyMessage = ""; - + decryptedJsonKey = getJsonKey(decryptAlgorithm); - + try { JSONParser parser = new JSONParser(); JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); - decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); + decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); } catch (ParseException e) { - e.printStackTrace(); - logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); - throw e; - } - - return decryptedBodyMessage; - - } - - private String getJsonKey(String Algorithm) { - - 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 = "preScreeningRequest"; - break; - case "AES256GCM": - break; - default: - break; - } - return jsonKey; - } - private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) { - - String decryptedJsonKey = ""; - String decryptedBodyMessage = ""; - - decryptedJsonKey = getJsonKey(decryptAlgorithm); - - try { - JSONParser parser = new JSONParser(); - JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); - decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + e.printStackTrace(); + logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + throw e; } return decryptedBodyMessage; - + } - + private String getJsonKey(String Algorithm) { - + String jsonKey = ""; - + switch (Algorithm) { - 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 = "preScreeningRequest"; - break; - case "AES256GCM": - break; - default: - break; + 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 = "preScreeningRequest"; + break; + case "AES256GCM": + break; + default: + break; } return jsonKey; } // 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; // 또는 에러 메시지 반환 - } + 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); + 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"); - // 복호화 수행 - byte[] decryptedBytes = cipher.doFinal(decodedBytes); + // 암호화와 동일한 알고리즘 설정 + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, key); - // UTF-8 문자열로 변환하여 반환 - //return new String(decryptedBytes, StandardCharsets.UTF_8); - //복호화된 바이트 배열 반환 - return decryptedBytes; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } + // 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 { @@ -1428,7 +1328,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return result; } - + public String getStringValue(Object obj) { if (obj == null) { return null; @@ -1566,4 +1466,4 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); return targetUrl; } -} \ No newline at end of file +}