diff --git a/libs/kjb-safedb.jar b/libs/kjb-safedb.jar new file mode 100644 index 0000000..884cbf4 Binary files /dev/null and b/libs/kjb-safedb.jar differ 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 0ddd235..db918b9 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 @@ -86,6 +86,7 @@ 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.nimbusds.jwt.SignedJWT; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; import com.eactive.eai.authserver.service.OAuth2Manager; @@ -114,6 +115,11 @@ 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; /** * 1. 기능 : REST API 통신에 사용
@@ -144,7 +150,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String headerGroupName = prop.getProperty(HEADER_GROUP); String relayResponseHeaderKeys = prop.getProperty(HEADER_KEYS, ""); - boolean useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); + useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); boolean useForwardProxy = StringUtils.equalsIgnoreCase(prop.getProperty("FORWARD_PROXY_USE_YN", "N"), "Y"); String forwardProxyUrl = prop.getProperty("FORWARD_PROXY_URL"); @@ -157,6 +163,9 @@ 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 요청에 대한 응답 메시지의 복호화 여부 결정위해 + encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y"); /** * @formatter:off @@ -287,6 +296,51 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp requestConfigBuilder.setProxy(proxy); } + // OAuth2AccessToken check 부분을 뒤에서 여기로 위치를 옮김, 나이스지키미 암호화 KEY를 얻기 위해서. JWHONG + OAuth2AccessTokenVO accessToken = null; + String auth =""; + if (useAdapterToken) { + AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); + accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, + oldToken); + } + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" + + accessToken + "]"); + } + + 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 { + setAuthHeaders(method, accessToken); // 원래 있던 logic + } + + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); + } + } + + if(!StringUtils.isBlank(authToken)) { + setAuthHeaders(method, authToken); + } + // 여기 까지 + configureHttpClient(requestConfigBuilder, vo, method); switch (HttpMethodType.getValue(rmethod)) { @@ -311,7 +365,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp case POST: // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName()); + assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth); break; default: break; @@ -322,39 +376,12 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + method.getEntity() + "] "); } - OAuth2AccessTokenVO accessToken = null; - if (useAdapterToken) { - AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); - accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); - - // 토큰이 없거나 만료 됐으면 재발급 - if (accessToken == null || accessToken.isExpired()) { - String oldToken = accessToken == null ? null : accessToken.getAccessToken(); - accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, - oldToken); - } - - if (logger.isDebug()) { - logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" - + accessToken + "]"); - } - - setAuthHeaders(method, accessToken); - - if (logger.isDebug()) { - logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() - + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); - } - } - - if(!StringUtils.isBlank(authToken)) { - setAuthHeaders(method, authToken); - } + // OAuth2AccessToken 원래 있던 위치 JWHONG // 전달 header 셋팅 // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) assignRequestHeaders(method, httpHeader); - + int status = -1; try { @@ -396,7 +423,6 @@ 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 - String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); // jwhong try { if (logger.isDebug()) { @@ -414,7 +440,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp responseMessageOri = EntityUtils.toByteArray(response.getEntity()); System.out.println("responseMessageOri 바이트 배열 길이: " + responseMessageOri.length); - responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName()); // jwhong + responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 responseHeaders = response.getHeaders(); @@ -682,6 +708,37 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } + + /* 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, accessToken.getAccessToken())); + } + + /* 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); + } catch (Exception e) { + logger.error(e.getMessage()); + tokenClientId = ""; + } + + System.out.println("Token Client ID: " + tokenClientId); + return tokenClientId; + + } + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, String encode) { @@ -737,7 +794,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName) { + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth) { if (eaiBody == null) { return; } @@ -758,7 +815,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } else { ContentType contentTypeObj = ContentType.create(contentType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody,adapterName); // jwhong + String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth); // jwhong StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); @@ -768,12 +825,15 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } } - private String doOutboundPreFilter(Object eaiBody, String adapterName) { + // from here by jwhong + private String doOutboundPreFilter(Object eaiBody, String adapterName, String niceAuth) { Properties properties = AdapterPropManager.getInstance().getProperties(adapterName); // jwhong String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong - String encryptBaseKeyType = properties.getProperty("ENCRYPT_BASE_TYPE"); + //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로 사용된다. // 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다. @@ -781,19 +841,30 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp OAuth2Manager manager = OAuth2Manager.getInstance(); ClientDetails clientDetail = manager.getClientDeatilsStore().get(encryptClientId); String clientSecret = ""; - if ( clientDetail != null ) { + if ( clientDetail != null ) { // not null 이라는 것은 APIM Oauth Server에 등록된 client ID 이다. + // 이건 KJBank로 Outbound 나가는 것임 clientSecret = clientDetail.getClientSecret(); + } else { // 그럼 업체로 Outbound 나가는것은, 업체에서 사용하는 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); + String responseMessage = doOutboundPreEncrypt(eaiBody, encryptAlgorithm, clientSecret, encryptAES256Iv, encryptAES256Key); return responseMessage; } - private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey) { + private String doOutboundPreEncrypt(Object eaiBody, String encryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { String encryptedMessage = ""; + String encryptedJsonKey = ""; + + encryptedJsonKey = getJsonKey(encryptAlgorithm); switch (encryptAlgorithm) { case "AES": @@ -818,12 +889,33 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } 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 "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(); @@ -844,18 +936,31 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp break; default: encryptedMessage = eaiBody.toString(); - break; + return encryptedMessage; + //break; } - return encryptedMessage; + + 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) { + 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 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(); @@ -863,18 +968,26 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String clientSecret = ""; if ( clientDetail != null ) { clientSecret = clientDetail.getClientSecret(); + } else { + clientSecret = encryptClientId; } - // 여기서 SECRETY인지 nice-auth 인지 check 하여 clientSecret 값을 정하는 logic 추가하여 넘겨야한다. - byte[] resPostMessage = doOutboundPostDecrypt(eaiBody, decryptAlgorithm, clientSecret); + // 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) { + private byte[] doOutboundPostDecrypt(byte[] eaiBody, String decryptAlgorithm, String clientSecretKey, String encryptAES256Iv, String encryptAES256Key ) { byte[] decryptedMessage = null; String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); + //test source System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); System.out.println("Base64 문자열: " + eaiStringBody); @@ -897,7 +1010,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp 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) { @@ -908,7 +1020,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp 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) { @@ -926,6 +1037,34 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp 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(); @@ -952,6 +1091,56 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } + 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()); + } + + 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; + } + return jsonKey; + } // by jwhong private String encrypt(String plainText) { try { 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 f83d8f3..a989dfd 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 @@ -75,6 +75,8 @@ public interface HttpAdapterServiceKey { 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 ENCRYPT_AES256_IV = "ENCRYPT_AES256_IV"; // jwhong + static final String ENCRYPT_AES256_KEY = "ENCRYPT_AES256_KEY"; // jwhong //응답 처리 용 표준 전문 오브젝트 static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java index c1aef65..6316890 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -96,7 +96,8 @@ public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientA if (!UrlUtils.isAbsoluteUrl(uri)) { uri = appendPath(adapterUrl, uri); } - String contentType = "application/json;"; + //String contentType = "application/json;"; // comment by jwhong + String contentType = "application/x-www-form-urlencoded"; // 광주은행 나이스지키미 Charset charset; if (StringUtils.isNotBlank(encode)) { diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java index 3772406..45e7c60 100644 --- a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -51,7 +51,7 @@ import com.openbanking.eai.common.token.AccessTokenVO; import com.openbanking.eai.common.token.OAuth2AccessTokenVO; import org.springframework.security.web.util.UrlUtils; -/** +/** * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 * retry 로직 제거 : 요청 3. 주의사항 * @@ -224,17 +224,20 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo logger.debug("contentType = [" + contentType + "]"); logger.debug("encode = [" + encode + "]"); + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { if (response.getCode() != 200) { + System.out.println("OAuth token receive status fail value= "+ response.getCode()); throw new Exception("OAuth token receive status fail value= " + response.getCode()); } + System.out.println("OAuth token receive status SUCCESS value= "+ response.getCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, encode); logger.debug("oauthToken RECV = [" + responseString + "]"); if (StringUtils.isNotBlank(responseString)) { - OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + //OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode responseJSON = objectMapper.readTree(responseString); @@ -259,6 +262,10 @@ public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTo } else { throw new Exception("oauth token return null"); } + } catch (Exception e) { + e.printStackTrace(); + logger.error("[HttpClientAccessTokenServiceWithParam] retrieve accessToken exception :" + e.getMessage()); + return accessToken; } } } 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 ae79af9..4dfc052 100644 --- a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -57,6 +57,10 @@ import com.eactive.eai.transformer.transform.Transform; import com.eactive.eai.transformer.transform.TransformManager; import com.eactive.eai.util.HexaConverter; import com.ext.eai.common.stdmessage.STDMessageKeys; +// safeDB +import com.eactive.ext.kjb.safedb.KjbSafedbWrapper; +import com.eactive.ext.kjb.safedb.Utils; +// until here @Service @@ -452,6 +456,7 @@ public class EAILogDAO { } // 암호화 + /* Charset hexaCharset = Charset.forName("euc-kr"); if ("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN())) { try { @@ -471,20 +476,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()); + biz = bizMsgStr; } } else { biz = bizMsgStr; } - */ + // jwhong safeDB end // 임시코드 시작 @@ -855,12 +862,121 @@ public class EAILogDAO { return false; } + + private String EncryptSafeDb(String attribute) { + String originalAttribute = attribute; + if (StringUtils.isNotEmpty(attribute)) { + KjbSafedbWrapper wrapper = KjbSafedbWrapper.getInstance(); + attribute = wrapper.encryptNotRnnoString(attribute); + + if (logger.isInfo()) { + // originalAttribute 홀수 글자 마스킹 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < originalAttribute.length(); i++) { + if (i % 2 == 0) { + sb.append(originalAttribute.charAt(i)); + } else { + sb.append("*"); + } + } + originalAttribute = sb.toString(); + System.out.println("DB 암호화 #2 : {"+ originalAttribute +"} -> {"+attribute+"}"); + //logger.debug("DB 암호화 #2 : {} -> {}", originalAttribute, attribute); + } + } + return attribute; + + } + + public String DecryptSafeDb(String dbData) { + + String dbDataOriginal = dbData; + if (StringUtils.isNotEmpty(dbData)) { + if (this.isEncrypted(dbData)) { + KjbSafedbWrapper safeDBWrapper = KjbSafedbWrapper.getInstance(); + try { + dbData = safeDBWrapper.decryptNotRnno(dbData); + } catch (Exception e) { + // 복호화 실패시 원본 반환 + String logData = dbData.length() <= 3 ? dbData : dbData.substring(0, 3) + "..."; + logger.warn("DB 복호화 실패: 복호화하지 않고 원본 반환. dbData={} (Length : {})", logData, dbData.length()); + return dbData; + } + } else { + logger.debug("DB 복호화 경고: Base64 형식이 아님. 복호화하지 않고 원본 반환. dbData={}", dbData); + } + } + + //logger.debug("DB 복호화 #2 : {} -> {}", dbDataOriginal, dbData); + + return dbData; + } + + /** + * 암호화 여부 확인(base64 인코딩 여부로 판단, 또는 0-9, - 로 구성된 경우 암호화 되지 않은 걸로 판단(연락처)) + * @param data + * @return + */ + private boolean isEncrypted(String data) { + if (StringUtils.isEmpty(data)) { + return false; + } + + // 숫자, - 로만 구성된 경우 암호화 되지 않은 걸로 판단 (ex: 연락처) + if (data.matches("^[0-9-]+$")) { + return false; + } + + data = data.trim(); + + // Base64 형식 체크 + if (!Utils.isBase64(data)) { + return false; + } + + // Base64 길이 체크 (4의 배수) + if (data.length() % 4 != 0) { + return false; + } + + + return true; + } + + + /* private String EncryptSafeDb(String msg) { PropManager propManager = PropManager.getInstance(); String safeDbPath = propManager.getProperty("SafeDB","safedb.path"); - return "this is a message"; + + SimpleSafeDB safedb = SimpleSafeDB.getInstance(); + boolean loginResult = false; + if(!safedb.login()) { + loginResult = safedb.getSafeDBConfigMgr().isLoginCheck(); + } + + String userName = "SAFEDB"; + String tableName = "SAFEDB.POLICY"; + String columnName1 = "bzwkdatactnt"; + + byte[] byteMsg = msg.getBytes(StandardCharsets.UTF_8); + byte[] encryptedBytes1 = null; + + try { + encryptedBytes1 = safedb.encrypt(userName, tableName, columnName1, byteMsg); + System.out.println("Encrypted Data : [" + new String(encryptedBytes1) + "]"); + + byte[] decryptedBytes1 = safedb.decrypt(userName, tableName, columnName1, encryptedBytes1); + + } catch (SafeDBSDKException e) { + e.printStackTrace(); + + } + + String encryptedMsg = new String(encryptedBytes1, StandardCharsets.UTF_8); + return encryptedMsg; } - - + */ + } diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java index eb38a42..0aba908 100644 --- a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -53,6 +53,10 @@ import com.eactive.eai.message.parser.StandardReader; import com.eactive.eai.message.service.InterfaceMapper; import com.eactive.eai.util.SimHeaderUtil; import com.ext.eai.common.stdmessage.STDMessageKeys; + +import org.json.simple.JSONObject; +import java.util.HashMap; +import java.util.Map; //import org.apache.commons.lang3.StringUtils; //import org.springframework.http.HttpStatus; @@ -1297,7 +1301,15 @@ public class RequestProcessor extends RequestProcessorSupport { } else { // 비동기 거래, S-A의 응답거래시에는 NULL을 리턴 - return null; + //return null; // 원래 null return 인데 광주은행은 GUID를 Return 해 달라고 해서 수정함 jwhong + //map.put("guid", guid); + + Map map = new HashMap<>(); + map.put("uuid", vo.getUuid()); + JSONObject json = new JSONObject(map); + //return json.toJSONString(); + + return vo.getUuid(); } }