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..da4f224 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,8 +86,10 @@ 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;
+import java.util.Set;
/**
@@ -114,6 +116,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 +151,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 +164,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 요청에 대한 응답 메시지의 복호화 여부 결정위해 jwhong
+ encryptResponseApply = StringUtils.equalsIgnoreCase(prop.getProperty("ENCRYPT_RESPONSE_APPLY", "N"), "Y");
/**
* @formatter:off
@@ -287,6 +297,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 +366,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 +377,15 @@ 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);
-
+
+ // KJBank API 추적정보를 Header에 제공. jwhong
+ assignRequestKJHeaders(method, prop, tempProp );
+
int status = -1;
try {
@@ -396,7 +427,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 +444,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 +712,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) {
@@ -736,8 +797,41 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
}
}
+ /*
+ * KJBank Target System으로 요청 보낼때 header에 clientId(업체정보), APIM거래추적자(UUID), 최초 요청시간 을 보낸다. jwhong
+ */
+ private void assignRequestKJHeaders(HttpUriRequestBase method, Properties prop, Properties tempProp) {
+
+ Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER);
+ String authorization = inboundHeaders.getProperty("authorization");
+ String jwtToken = "";
+
+ if (authorization != null && authorization.startsWith("Bearer ")) {
+ jwtToken = authorization.substring(7); // "Bearer " 이후의 JWT만 추출
+ //System.out.println("JWT Token: " + jwtToken);
+ }
+
+ /* 업체정보 */
+ String clientId = JwtClientIdExtractor(jwtToken);
+ method.setHeader("clientId", clientId);
+
+ /* APIM 거래추적자 */
+ String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
+ method.setHeader("traceId", uuid);
+
+ /* 최초요청시간 */
+ Set keys = tempProp.stringPropertyNames();
+ for (String key : keys) {
+ String value = tempProp.getProperty(key);
+ System.out.println(key + " = " + value);
+ }
+
+ String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, "");
+ method.setHeader("receivedTimestamp", receivedTimestamp);
+ }
+
@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 +852,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 +862,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 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로 사용된다.
// 참고로 inbound encrypt 에는 Token 또는 SecretKey 가 암호화 key로 사용된다.
@@ -781,19 +878,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 +926,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 +973,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 +1005,31 @@ 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);
+ try {
+ eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody);
+ } catch (ParseException e) {
+ System.out.println("JSON 파싱 오류 발생 : " +e.getMessage());
+ return eaiBody;
+ }
+
//test source
System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length);
System.out.println("Base64 문자열: " + eaiStringBody);
@@ -897,7 +1052,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 +1062,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 +1079,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 +1133,57 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
}
+ 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);
+ } 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-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..69bb8cf 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,9 @@ 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 INBOUND_REQUESTED_TIME = "INBOUND_REQUESTED_TIME"; // 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/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/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java
index c775498..d6930f8 100644
--- a/src/main/java/com/eactive/eai/common/util/JMSSender.java
+++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java
@@ -69,6 +69,7 @@ public class JMSSender {
throw new Exception("qconFactory not found -" + connectionFactory);
queue = locator.getQueue(destination);
+ logger.info("resolved quene name is:" + "["+ queue + "]");
qsender = qsession.createSender(queue);
ObjectMessage msg = qsession.createObjectMessage();
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();
}
}
diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java
index 1b2eb51..5e9c9a7 100644
--- a/src/main/java/com/eactive/eai/outbound/RESTProcess.java
+++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java
@@ -439,6 +439,7 @@ public class RESTProcess extends HTTPProcess {
PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_PATH_VARIABLES);
PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REMOTE_ADDR);
PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME);
+ PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REQUESTED_TIME); // jwhong
String svcName = getServiceId(this.reqEaiMsg);
if (svcName == null) {