From b22c8601c0bac85737a0f463d689bd0ec6e1f114 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 19 Nov 2025 15:50:27 +0900 Subject: [PATCH 01/14] =?UTF-8?q?=EA=B0=9C=EB=B0=9C=EC=84=9C=EB=B2=84?= =?UTF-8?q?=EC=97=90=20push=EC=9C=84=ED=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/server/EAIServerVO.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/server/EAIServerVO.java b/src/main/java/com/eactive/eai/common/server/EAIServerVO.java index 6f18c02..9f86f75 100644 --- a/src/main/java/com/eactive/eai/common/server/EAIServerVO.java +++ b/src/main/java/com/eactive/eai/common/server/EAIServerVO.java @@ -23,8 +23,8 @@ public class EAIServerVO implements Serializable { * 리모트 호출 url ==> rmi://{ip}:{rmi RegistryPort}/xxxxx * 사이트마다 다를수 있음. */ - //private int plusRmiPort = 1; - private int plusRmiPort = 11; //jwhong for weblogic + private int plusRmiPort = 1; + //private int plusRmiPort = 11; //jwhong for weblogic /** * sessionManager에서 쓰기위해 From ad5a5cbcfcd96426db8ab597413cf3199335a6a2 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 25 Nov 2025 16:19:31 +0900 Subject: [PATCH 02/14] =?UTF-8?q?ECDHESA256=20=EC=95=94=ED=98=B8=ED=99=94?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchange/crypto/ECDHESA256Cipher.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java new file mode 100644 index 0000000..a382e17 --- /dev/null +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java @@ -0,0 +1,112 @@ +package com.kjbank.encrypt.exchange.crypto; + +import com.nimbusds.jose.*; +import com.nimbusds.jose.crypto.*; +import com.nimbusds.jose.jwk.*; +import com.nimbusds.jose.jwk.gen.*; +import java.io.FileInputStream; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.security.KeyStore; +import java.security.PrivateKey; + +public class ECDHESA256Cipher { + + private ECKey myECKey; + private ECKey receiverPublicJWK; + + // 생성자: 수신자 키 쌍을 준비 + public ECDHESA256Cipher() throws Exception { + this.myECKey = new ECKeyGenerator(Curve.P_256) + .keyUse(KeyUse.ENCRYPTION) + .keyID("receiver-key") + .generate(); + + this.receiverPublicJWK = myECKey.toPublicJWK(); + } + + + //생성자: 내 키쌍 로드용 생성자 (복호화할 때 필요) + public ECDHESA256Cipher(String myKeystorePath, String storePass, String keyAlias, String keyPass) throws Exception { + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(new FileInputStream(myKeystorePath), storePass.toCharArray()); + + PrivateKey myPrivateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray()); + X509Certificate myCert = (X509Certificate) ks.getCertificate(keyAlias); + ECPublicKey myPublicKey = (ECPublicKey) myCert.getPublicKey(); + + this.myECKey = new ECKey.Builder(Curve.P_256, myPublicKey) + .privateKey(myPrivateKey) + .keyUse(KeyUse.ENCRYPTION) + //.keyID("my-key") + .keyID(myCert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용 + .build(); + } + + // 생성자: 상대방 인증서에서 공개키 로드 + public ECDHESA256Cipher(String certPath) throws Exception { + // 1. 인증서 로드 + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + try (FileInputStream fis = new FileInputStream(certPath)) { + X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); + + // 2. 공개키 추출 + ECPublicKey publicKey = (ECPublicKey) cert.getPublicKey(); + + // 3. Nimbus ECKey로 변환 + this.receiverPublicJWK = new ECKey.Builder(Curve.P_256, publicKey) + .keyUse(KeyUse.ENCRYPTION) + //.keyID("receiver-key") + .keyID(cert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용 + .build(); + } + } + + // 암호화 메서드 + public String encrypt(String jsonPayload) throws Exception { + if (receiverPublicJWK == null) { + throw new IllegalStateException("상대방 공개키가 초기화되지 않았습니다."); + } + + JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES_A256KW, EncryptionMethod.A256GCM) + .contentType("application/json") + .keyID(receiverPublicJWK.getKeyID()) + .build(); + + JWEObject jweObject = new JWEObject(header, new Payload(jsonPayload)); + + JWEEncrypter encrypter = new ECDHEncrypter(receiverPublicJWK); + jweObject.encrypt(encrypter); + + return jweObject.serialize(); + } + + // 복호화 메서드(상대방이 나한테 보낸것) + public String decrypt(String jweString) throws Exception { + if (myECKey == null) { + throw new IllegalStateException("내 개인키가 초기화되지 않았습니다."); + } + JWEObject decryptedJWE = JWEObject.parse(jweString); + JWEDecrypter decrypter = new ECDHDecrypter(myECKey); + decryptedJWE.decrypt(decrypter); + + return decryptedJWE.getPayload().toString(); + } + + // 상대방 공개키를 외부에 제공할 수 있도록 getter + public ECKey getReceiverPublicJWK() { + if (receiverPublicJWK == null) { + throw new IllegalStateException("상대방 공개키가 초기화되지 않았습니다."); + } + return receiverPublicJWK; + } + + // 내 공개키를 상대방에게 제공할 수 있도록 getter + public ECKey getMyPublicJWK() { + if (myECKey == null) { + throw new IllegalStateException("내 키쌍이 초기화되지 않았습니다."); + } + return myECKey.toPublicJWK(); + } +} From 410cd68b01caf1f0e721d30e09b4e1eaafea6ead Mon Sep 17 00:00:00 2001 From: jaewohong Date: Tue, 25 Nov 2025 17:34:19 +0900 Subject: [PATCH 03/14] =?UTF-8?q?ECDH-ES-A256KW=20=EC=95=94=ED=98=B8?= =?UTF-8?q?=ED=99=94=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 5173c19..fc88da4 100644 --- a/build.gradle +++ b/build.gradle @@ -65,6 +65,8 @@ dependencies { api "org.springframework:spring-context-support:${springVersion}" api 'jakarta.interceptor:jakarta.interceptor-api:2.1.0' + + implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3' //jwhong compileOnly group: 'com.ibm.db2', name: 'jcc', version: '11.5.7.0' From 49ff7ec36cf02a31e3b786fa5e2cf26714f0f63d Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 26 Nov 2025 16:31:01 +0900 Subject: [PATCH 04/14] =?UTF-8?q?nimbus-jose-jwt=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fc88da4..77012b9 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,14 @@ def hibernateVersion = "5.6.15.Final" def nexusUrl = "https://nexus.eactive.synology.me:8090" def generatedJavaDir = "$buildDir/generated/java" +// FOR LOCAL +repositories { + maven { + url "${nexusUrl}/repository/maven-public/" + allowInsecureProtocol = true + } +} +// java { toolchain { languageVersion = JavaLanguageVersion.of(8) @@ -66,7 +74,7 @@ dependencies { api 'jakarta.interceptor:jakarta.interceptor-api:2.1.0' - implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3' //jwhong + implementation 'com.nimbusds:nimbus-jose-jwt:9.24.3' //jwhong compileOnly group: 'com.ibm.db2', name: 'jcc', version: '11.5.7.0' From 69804f7a700b70374f5b207b5c56ea77940c128d Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Tue, 9 Dec 2025 13:46:58 +0900 Subject: [PATCH 05/14] =?UTF-8?q?=EA=B4=91=EC=A3=BC=EC=9D=80=ED=96=89=20?= =?UTF-8?q?=ED=91=9C=EC=A4=80=EC=A0=84=EB=AC=B8=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ext/eai/common/stdmessage/STDMessageKeys.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/ext/eai/common/stdmessage/STDMessageKeys.java b/src/main/java/com/ext/eai/common/stdmessage/STDMessageKeys.java index 00ba711..f4755c9 100644 --- a/src/main/java/com/ext/eai/common/stdmessage/STDMessageKeys.java +++ b/src/main/java/com/ext/eai/common/stdmessage/STDMessageKeys.java @@ -49,8 +49,9 @@ public interface STDMessageKeys { public static final String OUTPUT_TYPE_ERR = "02"; //응답결과구분코드 - public static final String RESPONSE_TYPE_CODE_N = "0";//정상(normal) - public static final String RESPONSE_TYPE_CODE_E = "1";//오류(error) + public static final String RESPONSE_TYPE_CODE_N = "NR";//정상(normal) + public static final String RESPONSE_TYPE_CODE_E = "ER";//오류(error) + public static final String RESPONSE_TYPE_CODE_C = "1";//대상시스템연결오류(connect fail) public static final String RESPONSE_TYPE_CODE_T = "1";//타임아웃(timeout) public static final String RESPONSE_TYPE_CODE_F = "1";//시스템오류(fatal) @@ -68,6 +69,9 @@ public interface STDMessageKeys { public static final String PUSH_DVSN_CD_R = "R";// 청단위 public static final String PUSH_DVSN_CD_B = "B";// 국단위 public static final String PUSH_DVSN_CD_A = "A";// 전체 - - + + public static final String SYS_OPRT_ENV_DVCD_ONLINE = "O"; //운영 + public static final String SYS_OPRT_ENV_DVCD_TESTSTAGE = "S"; //검증 + public static final String SYS_OPRT_ENV_DVCD_DEV = "D"; //테스트 + public static final String SYS_OPRT_ENV_DVCD_DR = "R"; //DR } From 48f657e04cc11ff71710f5bf36095af3adb83780 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 17 Dec 2025 09:31:45 +0900 Subject: [PATCH 06/14] =?UTF-8?q?PKI=20=EC=95=94=ED=98=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchange/crypto/ECDHESA256Cipher.java | 179 ++++++++++++++---- .../encrypt/exchange/crypto/NPKILoader.java | 60 ++++++ .../exchange/crypto/RSAOAEP256Cipher.java | 54 ++++++ 3 files changed, 259 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/kjbank/encrypt/exchange/crypto/NPKILoader.java create mode 100644 src/main/java/com/kjbank/encrypt/exchange/crypto/RSAOAEP256Cipher.java diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java index a382e17..6bd0530 100644 --- a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java @@ -7,14 +7,32 @@ import com.nimbusds.jose.jwk.gen.*; import java.io.FileInputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.cert.Certificate; import java.security.interfaces.ECPublicKey; import java.security.KeyStore; import java.security.PrivateKey; +//공개키 관련 (RSA) +import java.security.interfaces.RSAPublicKey; +import java.security.PublicKey; + +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.KeyUse; + +import java.io.FileNotFoundException; +import java.security.cert.CertificateException; +import java.io.IOException; +import java.util.Collection; +import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + public class ECDHESA256Cipher { private ECKey myECKey; private ECKey receiverPublicJWK; + private RSAKey receiverPublicRSAKey; + private PublicKey pubKey; + private JWEObject jweObject; // 생성자: 수신자 키 쌍을 준비 public ECDHESA256Cipher() throws Exception { @@ -28,70 +46,163 @@ public class ECDHESA256Cipher { //생성자: 내 키쌍 로드용 생성자 (복호화할 때 필요) - public ECDHESA256Cipher(String myKeystorePath, String storePass, String keyAlias, String keyPass) throws Exception { + // 생성자: 키스토어에서 RSA 개인키/인증서 로드 (복호화용) + public ECDHESA256Cipher(String keystorePath, String storePass, String keyAlias, String keyPass) throws Exception { KeyStore ks = KeyStore.getInstance("PKCS12"); - ks.load(new FileInputStream(myKeystorePath), storePass.toCharArray()); + try (FileInputStream fis = new FileInputStream(keystorePath)) { + ks.load(fis, storePass.toCharArray()); - PrivateKey myPrivateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray()); - X509Certificate myCert = (X509Certificate) ks.getCertificate(keyAlias); - ECPublicKey myPublicKey = (ECPublicKey) myCert.getPublicKey(); + PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray()); + X509Certificate cert = (X509Certificate) ks.getCertificate(keyAlias); - this.myECKey = new ECKey.Builder(Curve.P_256, myPublicKey) - .privateKey(myPrivateKey) - .keyUse(KeyUse.ENCRYPTION) - //.keyID("my-key") - .keyID(myCert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용 - .build(); + if (privateKey == null || cert == null) { + throw new IllegalStateException("키스토어에서 개인키 또는 인증서를 로드하지 못했습니다."); + } + + this.pubKey = cert.getPublicKey(); + System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" + + if ("RSA".equals(pubKey.getAlgorithm())) { + RSAPublicKey rsaPub = (RSAPublicKey) cert.getPublicKey(); + this.receiverPublicRSAKey = new RSAKey.Builder(rsaPub) + .privateKey(privateKey) // ★ 개인키 포함 + .keyUse(KeyUse.ENCRYPTION) + .keyID(cert.getSerialNumber().toString()) + .build(); + } else if ("EC".equals(pubKey.getAlgorithm())) { + ECPublicKey ecPub = (ECPublicKey) cert.getPublicKey(); + // EC 복호화를 위해서는 EC 개인키도 필요합니다. + this.myECKey = new ECKey.Builder(Curve.P_256, ecPub) + .privateKey(privateKey) + .keyUse(KeyUse.ENCRYPTION) + .keyID(cert.getSerialNumber().toString()) + .build(); + } else { + throw new IllegalStateException("지원하지 않는 공개키 알고리즘: " + pubKey.getAlgorithm()); + } + } } + // 생성자: 상대방 인증서에서 공개키 로드 public ECDHESA256Cipher(String certPath) throws Exception { + //0. 개인키 새성 + //String certPath = "C:/imsi/mytestcert/signCert.der"; + String priPath = "C:/imsi/mytestcert/signPri.key"; + char[] password = "looking100!".toCharArray(); + Security.addProvider(new BouncyCastleProvider()); + PrivateKey myPrivateKey1 = NPKILoader.loadPrivateKey(priPath, password, pubKey.getAlgorithm()); + // 1. 인증서 로드 CertificateFactory cf = CertificateFactory.getInstance("X.509"); try (FileInputStream fis = new FileInputStream(certPath)) { - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); + X509Certificate cert = null; + //인증서 묶음인 경우(PKCS#7 경우) + Collection certs = cf.generateCertificates(fis); + for (Certificate c : certs) { + if (c instanceof X509Certificate) { + cert = (X509Certificate) c; + System.out.println("Subject: " + cert.getSubjectDN()); + } + } + + if (cert == null) { + throw new IllegalStateException("인증서를 찾을 수 없습니다."); + } - // 2. 공개키 추출 - ECPublicKey publicKey = (ECPublicKey) cert.getPublicKey(); + // 공개키 저장 및 알고리즘 확인 + this.pubKey = cert.getPublicKey(); + System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" - // 3. Nimbus ECKey로 변환 - this.receiverPublicJWK = new ECKey.Builder(Curve.P_256, publicKey) - .keyUse(KeyUse.ENCRYPTION) - //.keyID("receiver-key") - .keyID(cert.getSerialNumber().toString()) // 인증서 시리얼번호를 keyID로 사용 - .build(); + KeyStore ks = KeyStore.getInstance("PKCS12"); + + if ("RSA".equals(pubKey.getAlgorithm())) { + //PrivateKey myPrivateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray()); + //PrivateKey myPrivateKey = (PrivateKey) ks.getKey("mykey", "key1234".toCharArray()); + PrivateKey myPrivateKey = NPKILoader.loadPrivateKey(priPath, password, pubKey.getAlgorithm()); + System.out.println("PrivateKey Alg: " + myPrivateKey.getAlgorithm()); + + RSAPublicKey publicKey = (RSAPublicKey) cert.getPublicKey(); + this.receiverPublicRSAKey = new RSAKey.Builder(publicKey) + .privateKey(myPrivateKey) //개인키 포함 + .keyUse(KeyUse.ENCRYPTION) + .keyID(cert.getSerialNumber().toString()) + .build(); + } else if ("EC".equals(pubKey.getAlgorithm())) { + ECPublicKey ecPub = (ECPublicKey) cert.getPublicKey(); + this.receiverPublicJWK = new ECKey.Builder(Curve.P_256, ecPub) + .keyUse(KeyUse.ENCRYPTION) + .keyID(cert.getSerialNumber().toString()) + .build(); + } else { + throw new IllegalStateException("지원하지 않는 공개키 알고리즘: " + pubKey.getAlgorithm()); + } + + } catch (FileNotFoundException e) { + System.err.println("인증서 파일을 찾을 수 없습니다: " + e.getMessage()); + } catch (CertificateException e) { + System.err.println("인증서 파싱 오류: " + e.getMessage()); + } catch (IOException e) { + System.err.println("파일 읽기 오류: " + e.getMessage()); + } catch (ClassCastException e) { + System.err.println("X509Certificate 형변환 오류: " + e.getMessage()); } } // 암호화 메서드 public String encrypt(String jsonPayload) throws Exception { - if (receiverPublicJWK == null) { + if (receiverPublicJWK == null && receiverPublicRSAKey == null ) { throw new IllegalStateException("상대방 공개키가 초기화되지 않았습니다."); } - - JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES_A256KW, EncryptionMethod.A256GCM) - .contentType("application/json") - .keyID(receiverPublicJWK.getKeyID()) - .build(); + + if (receiverPublicJWK != null && KeyType.EC.equals(receiverPublicJWK.getKeyType())) { + JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES_A256KW, EncryptionMethod.A256GCM) + .contentType("application/json") + .keyID(receiverPublicJWK.getKeyID()) + .build(); - JWEObject jweObject = new JWEObject(header, new Payload(jsonPayload)); + this.jweObject = new JWEObject(header, new Payload(jsonPayload)); - JWEEncrypter encrypter = new ECDHEncrypter(receiverPublicJWK); - jweObject.encrypt(encrypter); + JWEEncrypter encrypter = new ECDHEncrypter(receiverPublicJWK); + jweObject.encrypt(encrypter); + + } else if (receiverPublicRSAKey != null && "RSA".equals(receiverPublicRSAKey.getKeyType().getValue())) { + JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM) + .contentType("application/json") + .keyID(receiverPublicRSAKey.getKeyID()) + .build(); + this.jweObject = new JWEObject(header, new Payload(jsonPayload)); + + JWEEncrypter encrypter = new RSAEncrypter(receiverPublicRSAKey); + jweObject.encrypt(encrypter); + } return jweObject.serialize(); + } // 복호화 메서드(상대방이 나한테 보낸것) public String decrypt(String jweString) throws Exception { - if (myECKey == null) { - throw new IllegalStateException("내 개인키가 초기화되지 않았습니다."); + if (myECKey == null && receiverPublicRSAKey == null) { + throw new IllegalStateException("내 개인키 또는 RSA 키가 초기화되지 않았습니다."); } + JWEObject decryptedJWE = JWEObject.parse(jweString); - JWEDecrypter decrypter = new ECDHDecrypter(myECKey); - decryptedJWE.decrypt(decrypter); - return decryptedJWE.getPayload().toString(); + if (myECKey != null) { + // EC 키로 복호화 + JWEDecrypter decrypter = new ECDHDecrypter(myECKey); + decryptedJWE.decrypt(decrypter); + + } else if (receiverPublicRSAKey != null && receiverPublicRSAKey.isPrivate()) { + // RSA 키로 복호화 + JWEDecrypter decrypter = new RSADecrypter(receiverPublicRSAKey.toPrivateKey()); + decryptedJWE.decrypt(decrypter); + } else { + throw new IllegalStateException("복호화에 필요한 키가 준비되지 않았습니다. (EC 개인키 또는 RSA 개인키)"); + } + + return decryptedJWE.getPayload().toString(); } // 상대방 공개키를 외부에 제공할 수 있도록 getter diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/NPKILoader.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/NPKILoader.java new file mode 100644 index 0000000..aa84d9e --- /dev/null +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/NPKILoader.java @@ -0,0 +1,60 @@ +package com.kjbank.encrypt.exchange.crypto; + +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.*; +import java.security.cert.*; +import java.security.spec.PKCS8EncodedKeySpec; +import javax.crypto.*; +import javax.crypto.spec.PBEKeySpec; + +public class NPKILoader { + + // 1) Provider 등록 (예: KISA SEED JCE, KSign 등) + static { + // 예시: Security.addProvider(new com.kisa.seed.KISASeedJCE()); + // 또는 Security.addProvider(new com.ksign.security.provider.KsignProvider()); + // 실제 사용하는 라이브러리 명으로 교체 + } + + public static X509Certificate loadCert(String certDerPath) throws Exception { + try (FileInputStream fis = new FileInputStream(certDerPath)) { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return (X509Certificate) cf.generateCertificate(fis); + } + } + + public static PrivateKey loadPrivateKey(String priDerPath, char[] password, String keyAlg) throws Exception { + // 암호화된 PKCS#8 (DER) 읽기 + byte[] enc = Files.readAllBytes(Paths.get(priDerPath)); + EncryptedPrivateKeyInfo encInfo = new EncryptedPrivateKeyInfo(enc); + + // 알고리즘 확인 (OID → 알고리즘 이름 매핑 필요) + String algName = encInfo.getAlgName(); // 일부 Provider는 빈 문자열을 반환할 수 있음 + AlgorithmParameters params = encInfo.getAlgParameters(); + + // 국내 OID 매핑: 1.2.410.200004.1.15 → PBEWithSHA1AndSEED (Provider에 따라 이름 다를 수 있음) + if (algName == null || algName.isEmpty()) { + String oid = encInfo.getAlgParameters().getAlgorithm(); // 일부 Provider는 여기서도 OID를 줍니다 + // 필요 시 강제 설정 + algName = "PBEWithSHA1AndSEED"; // 사용 중인 Provider 문서의 이름으로 맞추세요 + } + + // PBE 키 생성 + SecretKeyFactory skf = SecretKeyFactory.getInstance(algName); + PBEKeySpec pbeKeySpec = new PBEKeySpec(password); + SecretKey pbeKey = skf.generateSecret(pbeKeySpec); + + // 복호화 + Cipher cipher = Cipher.getInstance(algName); + cipher.init(Cipher.DECRYPT_MODE, pbeKey, params); + byte[] pkcs8 = cipher.doFinal(encInfo.getEncryptedData()); + + // PKCS#8 → PrivateKey + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8); + KeyFactory kf = KeyFactory.getInstance(keyAlg); // "RSA" 또는 "EC" + return kf.generatePrivate(keySpec); + } +} + diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/RSAOAEP256Cipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/RSAOAEP256Cipher.java new file mode 100644 index 0000000..10d1790 --- /dev/null +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/RSAOAEP256Cipher.java @@ -0,0 +1,54 @@ +package com.kjbank.encrypt.exchange.crypto; + +import com.nimbusds.jose.*; +import com.nimbusds.jose.crypto.*; +import com.nimbusds.jose.util.StandardCharset; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import com.nimbusds.jose.crypto.RSAEncrypter; +import java.security.interfaces.RSAPublicKey; + +public class RSAOAEP256Cipher { + + // 암호화: 상대방 공개 인증서(RSA)로 암호화 + public static String encrypt(byte[] plaintext, X509Certificate recipientCert, String kidOptional) throws Exception { + // 인증서에서 RSA 공개키 추출 + if (!"RSA".equalsIgnoreCase(recipientCert.getPublicKey().getAlgorithm())) { + throw new IllegalArgumentException("Recipient certificate public key is not RSA"); + } + RSAPublicKey recipientPublicKey = (RSAPublicKey) recipientCert.getPublicKey(); + + JWEHeader header = new JWEHeader.Builder( + JWEAlgorithm.RSA_OAEP_256, + EncryptionMethod.A256GCM + ) + .contentType("application/octet-stream") + .keyID(kidOptional) + .build(); + + JWEObject jweObject = new JWEObject(header, new Payload(plaintext)); + JWEEncrypter encrypter = new RSAEncrypter(recipientPublicKey); + jweObject.encrypt(encrypter); + + return jweObject.serialize(); + } + + // 복호화: 내 RSA 개인키로 복호화 + public static byte[] decrypt(String jweCompact, PrivateKey myPrivateKey) throws Exception { + JWEObject jweObject = JWEObject.parse(jweCompact); + JWEDecrypter decrypter = new RSADecrypter(myPrivateKey); + jweObject.decrypt(decrypter); + return jweObject.getPayload().toBytes(); + } + + // 편의 함수 + public static String encryptText(String text, X509Certificate cert, String kidOptional) throws Exception { + return encrypt(text.getBytes(StandardCharset.UTF_8), cert, kidOptional); + } + + public static String decryptToText(String jweCompact, PrivateKey myPrivateKey) throws Exception { + return new String(decrypt(jweCompact, myPrivateKey), StandardCharset.UTF_8); + } +} \ No newline at end of file From 75e3d3451c0965ad7bbf88a469211afb75f3dc5f Mon Sep 17 00:00:00 2001 From: jaewohong Date: Wed, 17 Dec 2025 10:33:47 +0900 Subject: [PATCH 07/14] =?UTF-8?q?BouncyCastleProvider=20=EC=9D=BC=EB=8B=A8?= =?UTF-8?q?=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java index 6bd0530..4eceffd 100644 --- a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java @@ -24,7 +24,7 @@ import java.security.cert.CertificateException; import java.io.IOException; import java.util.Collection; import java.security.Security; -import org.bouncycastle.jce.provider.BouncyCastleProvider; +//import org.bouncycastle.jce.provider.BouncyCastleProvider; public class ECDHESA256Cipher { @@ -89,8 +89,8 @@ public class ECDHESA256Cipher { //0. 개인키 새성 //String certPath = "C:/imsi/mytestcert/signCert.der"; String priPath = "C:/imsi/mytestcert/signPri.key"; - char[] password = "looking100!".toCharArray(); - Security.addProvider(new BouncyCastleProvider()); + char[] password = "aaa1001".toCharArray(); + //Security.addProvider(new BouncyCastleProvider()); // bouncycastle 관련 일단 comment PrivateKey myPrivateKey1 = NPKILoader.loadPrivateKey(priPath, password, pubKey.getAlgorithm()); // 1. 인증서 로드 From b8e07a0cc450493b62caa11699150ed058a6b6b1 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Wed, 7 Jan 2026 16:44:33 +0900 Subject: [PATCH 08/14] =?UTF-8?q?ElinkTransactionContext=20=EC=9E=91?= =?UTF-8?q?=EC=97=85(=EB=B3=80=ED=99=98=20=ED=95=A8=EC=88=98=EC=97=90=20?= =?UTF-8?q?=EA=B0=92=20=EC=A0=84=EB=8B=AC=20=EC=B2=B4=EA=B3=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../context/ElinkTransactionContext.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java diff --git a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java new file mode 100644 index 0000000..36adc9d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java @@ -0,0 +1,99 @@ +package com.eactive.eai.common.context; + +import java.util.HashMap; +import java.util.Map; + +/** + * 트랜잭션 범위 컨텍스트 관리 + * - ThreadLocal 기반으로 현재 스레드의 트랜잭션 컨텍스트 관리 + * - Lazy initialization: 최초 put 시 자동 생성 + * - 비동기 전달: getAll()로 복사본 획득, restore()로 복원 + * + *
+ * [동기 거래]
+ * ApiAdapterController → ... → JEP 함수에서 set/get → ... → finally { clear() }
+ *
+ * [비동기 거래]
+ * 송신측: FlowRouter → eaiMessage.setTransactionContextTransfer(getAll()) → JMS Queue
+ * 수신측: Consumer → ElinkESBProcessProxy → restore(transfer) → JEP 함수 → clear()
+ * 
+ */ +public class ElinkTransactionContext { + + private static final ThreadLocal> THREAD_LOCAL = new ThreadLocal<>(); + + // Context Map Keys + private static final String KEY_SEED_SALT = "SEED_SALT"; + private static final String KEY_ENCRYPTION_KEY = "ENCRYPTION_KEY"; + + // ==================== 컨텍스트 관리 ==================== + + /** + * 컨텍스트 정리 (필수) + * - 동기: ApiAdapterController finally 블록에서 호출 + * - 비동기: ElinkESBProcessProxy finally 블록에서 호출 + */ + public static void clear() { + THREAD_LOCAL.remove(); + } + + /** + * 비동기 전달용 컨텍스트 복사본 반환 + * - FlowRouter에서 JMS 송신 전 호출 + * - 컨텍스트가 없으면 null 반환 + */ + public static Map getAll() { + Map ctx = THREAD_LOCAL.get(); + return ctx != null ? new HashMap<>(ctx) : null; + } + + /** + * 비동기 수신 시 컨텍스트 복원 + * - ElinkESBProcessProxy에서 비동기 거래 처리 시작 시 호출 + */ + public static void restore(Map transferContext) { + if (transferContext != null && !transferContext.isEmpty()) { + THREAD_LOCAL.set(new HashMap<>(transferContext)); + } + } + + // ==================== 내부 헬퍼 ==================== + + private static Map getOrCreate() { + Map ctx = THREAD_LOCAL.get(); + if (ctx == null) { + ctx = new HashMap<>(); + THREAD_LOCAL.set(ctx); + } + return ctx; + } + + private static void put(String key, Object value) { + if (value != null) { + getOrCreate().put(key, value); + } + } + + private static String get(String key) { + Map ctx = THREAD_LOCAL.get(); + return ctx != null ? (String) ctx.get(key) : null; + } + + // ==================== 명시적 변수 접근자 ==================== + + public static void setSeedSalt(String seedSalt) { + put(KEY_SEED_SALT, seedSalt); + } + + public static String getSeedSalt() { + return get(KEY_SEED_SALT); + } + + public static void setEncryptionKey(String encryptionKey) { + put(KEY_ENCRYPTION_KEY, encryptionKey); + } + + public static String getEncryptionKey() { + return get(KEY_ENCRYPTION_KEY); + } +} From c84c063b43b23d4d2f39a5a656f43e2e6c00f828 Mon Sep 17 00:00:00 2001 From: jaewohong Date: Thu, 8 Jan 2026 13:49:33 +0900 Subject: [PATCH 09/14] =?UTF-8?q?local=20thread=20data=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/common/context/ElinkTransactionContext.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java index 36adc9d..a591588 100644 --- a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java +++ b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java @@ -25,6 +25,7 @@ public class ElinkTransactionContext { // Context Map Keys private static final String KEY_SEED_SALT = "SEED_SALT"; private static final String KEY_ENCRYPTION_KEY = "ENCRYPTION_KEY"; + private static final String SEED_KEY = "SEED_KEY"; // ==================== 컨텍스트 관리 ==================== @@ -96,4 +97,14 @@ public class ElinkTransactionContext { public static String getEncryptionKey() { return get(KEY_ENCRYPTION_KEY); } + + // ==================== 실 사용 변수 접근자 ==================== + + public static void setSeedKey(String encryptionKey) { + put(SEED_KEY, encryptionKey); + } + + public static String getSeedKey() { + return get(SEED_KEY); + } } From 6108790fdbcbfd270ac13cce4aed3620ae8c16b0 Mon Sep 17 00:00:00 2001 From: yunjy-hp Date: Thu, 8 Jan 2026 15:07:59 +0900 Subject: [PATCH 10/14] =?UTF-8?q?ElinkTransactionContext=EC=97=90=20?= =?UTF-8?q?=EC=B5=9C=EC=B4=88=EC=9A=94=EC=B2=AD=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EA=B0=80=EC=A0=B8=EB=8B=A4?= =?UTF-8?q?=20=EC=93=B0=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/common/context/ElinkTransactionContext.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java index a591588..e16884e 100644 --- a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java +++ b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java @@ -26,6 +26,7 @@ public class ElinkTransactionContext { private static final String KEY_SEED_SALT = "SEED_SALT"; private static final String KEY_ENCRYPTION_KEY = "ENCRYPTION_KEY"; private static final String SEED_KEY = "SEED_KEY"; + public static final String REQUEST_BIZ_DATA = "REQUEST_BIZ_DATA"; // ==================== 컨텍스트 관리 ==================== @@ -97,7 +98,7 @@ public class ElinkTransactionContext { public static String getEncryptionKey() { return get(KEY_ENCRYPTION_KEY); } - + // ==================== 실 사용 변수 접근자 ==================== public static void setSeedKey(String encryptionKey) { @@ -107,4 +108,12 @@ public class ElinkTransactionContext { public static String getSeedKey() { return get(SEED_KEY); } + + public static void setRequestBizData(String bizData) { + put(REQUEST_BIZ_DATA, bizData); + } + + public static String getRequestBizData() { + return get(REQUEST_BIZ_DATA); + } } From f1d5b0e4ca966ad49609f55f187ff0688596dd4e Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 26 Feb 2026 19:17:51 +0900 Subject: [PATCH 11/14] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EB=A0=88=EB=B2=A8?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/monitor/MonitorVO.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java b/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java index e8daeba..b5fb025 100644 --- a/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java @@ -370,8 +370,8 @@ public class MonitorVO implements Serializable //if (logger.isError()) logger.error("MonitorVO["+this.eaiServiceCode+"] "+svcOgNo+" - "+logSequence+" ["+iErrorCode+"] : "+msgRcvTm+" / "+(msgPssTm-msgRcvTm)+" msec",e); //throw new Exception("RECEAICMT101"); // String msg = ErrorCodeHandler.getMessage("RECEAICMT101", new String[]{this.eaiServiceCode, svcOgNo, String.valueOf(logSequence), String.valueOf(iErrorCode), String.valueOf(msgRcvTm), String.valueOf(msgPssTm-msgRcvTm)}); - if (logger.isError()) { - logger.error(ExceptionUtil.make(e, "RECEAICMT101"), e); + if (logger.isInfo()) { + logger.info(ExceptionUtil.make(e, "RECEAICMT101"), e); } } } From 3d6fe754daa88e45cd6015e28107518ce6d3b3b1 Mon Sep 17 00:00:00 2001 From: cho Date: Fri, 27 Feb 2026 13:48:46 +0900 Subject: [PATCH 12/14] =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/eactive/eai/common/monitor/MonitorVO.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java b/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java index b5fb025..5c830c8 100644 --- a/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorVO.java @@ -1014,7 +1014,11 @@ public class MonitorVO implements Serializable **/ synchronized private void countM02(String logSeq, long msgPssTm, long msgRcvTm, int iErrorCode){ if(iErrorCode == 0){ - long psstmp = Long.parseLong((this.pssCnt.get(logSeq).toString())); + Object o = this.pssCnt.get(logSeq); + long psstmp = 0; + if( o != null ) { + psstmp = Long.parseLong((this.pssCnt.get(logSeq).toString())); + } long psstmpIn = Long.parseLong((this.pssCntInPeriod.get(logSeq).toString())); psstmp++; psstmpIn++; From 8c886f92fb48f9a5a0aa4cc80636016156b28295 Mon Sep 17 00:00:00 2001 From: cho Date: Tue, 3 Mar 2026 14:04:32 +0900 Subject: [PATCH 13/14] =?UTF-8?q?system=5Fout=5F=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/seed/Seed.java | 2 +- .../eai/common/server/EAIServerManager.java | 6 ++--- .../eactive/eai/common/util/StringUtil.java | 26 +++++++++---------- .../eai/common/util/TypeConversion.java | 14 +++++----- .../eai/common/util/UUIDGenerator.java | 8 +++--- .../encrypt/exchange/crypto/AESCipher.java | 2 +- .../exchange/crypto/ECDHESA256Cipher.java | 8 +++--- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/seed/Seed.java b/src/main/java/com/eactive/eai/common/seed/Seed.java index 9d2a578..fe88f1a 100644 --- a/src/main/java/com/eactive/eai/common/seed/Seed.java +++ b/src/main/java/com/eactive/eai/common/seed/Seed.java @@ -10,7 +10,7 @@ public class Seed { public static void main(String[] args) throws Exception { - System.out.println( Seed.decrypt("47T1fWZ+PqF2pqseL++jLg==")); + // System.out.println( Seed.decrypt("47T1fWZ+PqF2pqseL++jLg==")); // //// String planText = "AIORTA00051001001R0000AIORULE01 0000001 0821400646003112000000004721212121061705G30011 0000000000006520507000000000000000000000000010200 1000000000000000000000000000000000000000000000000000000000000000000000000011000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000001400000091 90 92 Q 21000000000000000000000004000000000000005000000000000000000000000000004000000000000000000100000000004000000646000000000000000FR00200000000400000000330906REJECT G301 00652 31742FILTER F200 0102721 R001 0000 0000 0000 0000 0000 30840MAIN G300 0061707 06 P3501 P4401 P4601 N4501 P3402 P4201 00000235143TEMP 31955TEMP 00000000231758TEMP 30623TEMP 00004830906BASE00 G301_BASE00 N 000000000000000000000025230906L11210000 G301_L11210000_37 N 000000000000000000000003730906L9Z000007 G301_L9Z000007_42 N 000000000000000000000004230906L9Z000210 G301_L9Z000210_47 N 000000000000000000000004730906CF0342210 G301_CF0342210_26 N 000000000000000000000002630906CF1200610 G301_CF1200610_00 N 000000000000000000000000030906L21210100 G301_L21210100_57 N 000000000000000000000005730906LA0600104 G301_LA0600104_55 N 000000000000000000000005530906LC0000008 G301_LC0000008_00 N 000000000000000000000000030906PE0000026 G301_PE0000026_90 N 000000000000000000000009030906NPF003_D G301_NPF003_D_46 S92 0004631742CD002 CD002_A 0000 N 000000000000000000000000031742FR002 FR002_A 0000 N 000000000000000000000000031742FR003 FR003_A 0000 N 000000000000000000000000031742FR004 FR004_A 0000 N 000000000000000000000000031742FR005 FR005_A 0000 N 000000000000000000000000031742FR006 FR006_A 0000 N 000000000000000000000000031742FR007 FR007_A 0000 N 000000000000000000000000031742IA004 IA004_R R001 N 000000000000000000000102731742LD002 LD002_A 0000 N 000000000000000000000000031742D10210000 D10210000_A 0000 N 000000000000000000000000031742D10210600 D10210600_A 0000 N 000000000000000000000000031742D20210000 D20210000_A 0000 N 000000000000000000000000031742D30210000 D30210000_A 0000 N 000000000000000000000000031742P27000100 P27000100_A 0000 N 000000000000000000000000031742XZ021 XZ021_A 0000 N 000000000000000000000000031742B12000200 B12000200_A 0000 N 000000000000000000000000031742B22000200 B22000200_A 0000 N 000000000000000000000000031742LE0021201 LE0021201_A 0000 N 000000000000000000000000031742L21201300 L21201300_A 0000 N 000000000000000000000000031742NLD010 NLD010_A 0000 N 000000000000000000000000031742G20220L00 G20220L00_A 0000 N 000000000000000000000000030840BASE00 G300_BASE00 N 000000000000000000000026130840NPF003 G300_NPF003_00 S91 0000030840NPF004 G300_NPF004_00 N 000000000000000000000000030840P13000500 G300_P13000500_32 N 000000000000000000000003230840PH0000043 G300_PH0000043_53 P4601 N 000000000000000000000005330840LC0027001 G300_LC0027001_23 P2401 N 000000000000000000000002330840NCBTM206A G300_NCBTM206A_47 P4401 N 000000000000000000000004730840L9Z000006 G300_L9Z000006_29 P3402 N 000000000000000000000002930840L11210000 G300_L11210000_30 N 000000000000000000000003030840U5Z000015 G300_U5Z000015_10 N 000000000000000000000001030840CF1200610 G300_CF1200610_00 N4501 N 000000000000000000000000030840C1Z200031 G300_C1Z200031_77 P3501 N 000000000000000000000007730840CF0642229 G300_CF0642229_09 N 000000000000000000000000930840L21210100 G300_L21210100_46 P4201 N 000000000000000000000004630840LC0000008 G300_LC0000008_00 N 000000000000000000000000030840KCBC14063 G300_KCBC14063_00 N 0000000000000000000000000";//2Byte이상의 문자 취 // String planText = "";//2Byte이상의 문자 취 diff --git a/src/main/java/com/eactive/eai/common/server/EAIServerManager.java b/src/main/java/com/eactive/eai/common/server/EAIServerManager.java index 477be4a..0b144d3 100644 --- a/src/main/java/com/eactive/eai/common/server/EAIServerManager.java +++ b/src/main/java/com/eactive/eai/common/server/EAIServerManager.java @@ -369,9 +369,9 @@ public class EAIServerManager implements Lifecycle { } } public static void main(String[] args) throws Exception{ - System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[5,2],[5,2],[-2]",0)); - System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[5,2],[5,2],[-2]",1)); - System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[0,2],[0,2],[-2]",2)); + // System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[5,2],[5,2],[-2]",0)); + // System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[5,2],[5,2],[-2]",1)); + // System.out.println(substrRule("card-internal-runtime-568fd58554-b2cnk","[0,2],[0,2],[-2]",2)); } } diff --git a/src/main/java/com/eactive/eai/common/util/StringUtil.java b/src/main/java/com/eactive/eai/common/util/StringUtil.java index 04d3718..3a856af 100644 --- a/src/main/java/com/eactive/eai/common/util/StringUtil.java +++ b/src/main/java/com/eactive/eai/common/util/StringUtil.java @@ -644,26 +644,26 @@ public final class StringUtil { boolean isDBUtf8 = true; String[] chunks = null; - System.out.println("\n test string:" + test); - System.out.println("utf-8 length = " + getBytesLength(test, true)); - System.out.println("ms949 length = " + getBytesLength(test, false)); - System.out.println("\n"); + // System.out.println("\n test string:" + test); + // System.out.println("utf-8 length = " + getBytesLength(test, true)); + // System.out.println("ms949 length = " + getBytesLength(test, false)); + // System.out.println("\n"); for(int len=6; len<9; len++) { - System.out.println(String.format(">> chunk length=%d, isDBUtf8=%b",len, isDBUtf8)); + // System.out.println(String.format(">> chunk length=%d, isDBUtf8=%b",len, isDBUtf8)); chunks = chunkStringArray(test,len,isDBUtf8); - System.out.println("chunk = "+ chunkString(test,len,isDBUtf8)); - System.out.println("chunks[0] = "+ chunks[0]); - System.out.println("chunks[1] = "+ chunks[1]); + // System.out.println("chunk = "+ chunkString(test,len,isDBUtf8)); + // System.out.println("chunks[0] = "+ chunks[0]); + // System.out.println("chunks[1] = "+ chunks[1]); } - System.out.println("\n"); + // System.out.println("\n"); isDBUtf8 = false; for(int len=6; len<9; len++) { - System.out.println(String.format(">> chunk length=%d, isDBUtf8=%b",len, isDBUtf8)); + // System.out.println(String.format(">> chunk length=%d, isDBUtf8=%b",len, isDBUtf8)); chunks = chunkStringArray(test,len,isDBUtf8); - System.out.println("chunk = "+ chunkString(test,len,isDBUtf8)); - System.out.println("chunks[0] = "+ chunks[0]); - System.out.println("chunks[1] = "+ chunks[1]); + // System.out.println("chunk = "+ chunkString(test,len,isDBUtf8)); + // System.out.println("chunks[0] = "+ chunks[0]); + // System.out.println("chunks[1] = "+ chunks[1]); } } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/TypeConversion.java b/src/main/java/com/eactive/eai/common/util/TypeConversion.java index cb75489..ddf7f66 100644 --- a/src/main/java/com/eactive/eai/common/util/TypeConversion.java +++ b/src/main/java/com/eactive/eai/common/util/TypeConversion.java @@ -229,27 +229,27 @@ public class TypeConversion short sInit = 730; byte[] bytes = TypeConversion.short2byte(sInit); short sLL = TypeConversion.parseShort(bytes,0); - System.out.println("-----Message Old LL : " + sLL); - System.out.println("-----Message bytes toString : " + bytes); + // System.out.println("-----Message Old LL : " + sLL); + // System.out.println("-----Message bytes toString : " + bytes); short sNewLL = 152; bytes = TypeConversion.replaceShort(bytes, 0, sNewLL); sNewLL = TypeConversion.parseShort(bytes,0); - System.out.println("-----Message New LL : " + sNewLL); - System.out.println("-----Message bytes toString : " + bytes); + // System.out.println("-----Message New LL : " + sNewLL); + // System.out.println("-----Message bytes toString : " + bytes); String strMsg = "DA F23456789012345678901234567890123456 "; short minusOne = -1; byte[] bytesMsg = strMsg.getBytes(); bytesMsg = TypeConversion.replaceShort(bytesMsg, 47, minusOne); - System.out.println("-----minusOne : [" + new String(bytesMsg)+"]"); + // System.out.println("-----minusOne : [" + new String(bytesMsg)+"]"); short rtnMinusOne = TypeConversion.parseShort(bytesMsg, 47); - System.out.println("-----minusOne : [" + rtnMinusOne+"]"); + // System.out.println("-----minusOne : [" + rtnMinusOne+"]"); bytesMsg = TypeConversion.replaceShort(bytesMsg, 0, sNewLL); - System.out.println("-----minusOne : [" + new String(bytesMsg)+"]"); + // System.out.println("-----minusOne : [" + new String(bytesMsg)+"]"); } diff --git a/src/main/java/com/eactive/eai/common/util/UUIDGenerator.java b/src/main/java/com/eactive/eai/common/util/UUIDGenerator.java index 1b553aa..192148c 100644 --- a/src/main/java/com/eactive/eai/common/util/UUIDGenerator.java +++ b/src/main/java/com/eactive/eai/common/util/UUIDGenerator.java @@ -129,8 +129,8 @@ public final class UUIDGenerator { // System.out.println(getGUID("user000001")); // System.out.println(new Integer("01")); seq = 99999999; - System.out.println(getGUID("MCI")); - System.out.println(getGUID("MCI")); + // System.out.println(getGUID("MCI")); + // System.out.println(getGUID("MCI")); long start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { char[] seq = String.valueOf(i).toCharArray(); @@ -139,14 +139,14 @@ public final class UUIDGenerator { System.arraycopy(seq, 0, formatSeq, destPos, seq.length); } long end = System.currentTimeMillis() - start; - System.out.println("c1 time-" + end); + // System.out.println("c1 time-" + end); start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { String formatSeq = StringUtils.leftPad(String.valueOf(i), 10, '0'); } end = System.currentTimeMillis() - start; - System.out.println("c2 time-" + end); + // System.out.println("c2 time-" + end); // System.out.println(formatSeq); } diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/AESCipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/AESCipher.java index 7241637..4306508 100644 --- a/src/main/java/com/kjbank/encrypt/exchange/crypto/AESCipher.java +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/AESCipher.java @@ -110,7 +110,7 @@ public class AESCipher } catch (Exception e) { - System.out.println(e.toString()); + // System.out.println(e.toString()); } return resultData; diff --git a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java index 4eceffd..2c99d15 100644 --- a/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java +++ b/src/main/java/com/kjbank/encrypt/exchange/crypto/ECDHESA256Cipher.java @@ -60,7 +60,7 @@ public class ECDHESA256Cipher { } this.pubKey = cert.getPublicKey(); - System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" + // System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" if ("RSA".equals(pubKey.getAlgorithm())) { RSAPublicKey rsaPub = (RSAPublicKey) cert.getPublicKey(); @@ -102,7 +102,7 @@ public class ECDHESA256Cipher { for (Certificate c : certs) { if (c instanceof X509Certificate) { cert = (X509Certificate) c; - System.out.println("Subject: " + cert.getSubjectDN()); + // System.out.println("Subject: " + cert.getSubjectDN()); } } @@ -112,7 +112,7 @@ public class ECDHESA256Cipher { // 공개키 저장 및 알고리즘 확인 this.pubKey = cert.getPublicKey(); - System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" + // System.out.println(pubKey.getAlgorithm()); // "RSA" 또는 "EC" KeyStore ks = KeyStore.getInstance("PKCS12"); @@ -120,7 +120,7 @@ public class ECDHESA256Cipher { //PrivateKey myPrivateKey = (PrivateKey) ks.getKey(keyAlias, keyPass.toCharArray()); //PrivateKey myPrivateKey = (PrivateKey) ks.getKey("mykey", "key1234".toCharArray()); PrivateKey myPrivateKey = NPKILoader.loadPrivateKey(priPath, password, pubKey.getAlgorithm()); - System.out.println("PrivateKey Alg: " + myPrivateKey.getAlgorithm()); + // System.out.println("PrivateKey Alg: " + myPrivateKey.getAlgorithm()); RSAPublicKey publicKey = (RSAPublicKey) cert.getPublicKey(); this.receiverPublicRSAKey = new RSAKey.Builder(publicKey) From c22786b72926f2a6180a8d5085f37a5f6c86068d Mon Sep 17 00:00:00 2001 From: cho Date: Thu, 5 Mar 2026 11:53:04 +0900 Subject: [PATCH 14/14] =?UTF-8?q?=EB=A1=9C=EA=B1=B0=20=EB=A1=A4=EB=A7=81?= =?UTF-8?q?=20=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=20time->=20size(500M?= =?UTF-8?q?B)=20and=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/eactive/eai/common/util/LogKeys.java | 1 + .../com/eactive/eai/common/util/Logger.java | 28 +++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/eactive/eai/common/util/LogKeys.java b/src/main/java/com/eactive/eai/common/util/LogKeys.java index ba6ee90..ecff4ee 100644 --- a/src/main/java/com/eactive/eai/common/util/LogKeys.java +++ b/src/main/java/com/eactive/eai/common/util/LogKeys.java @@ -47,6 +47,7 @@ public interface LogKeys public static final String DATE_PATTERN ="date.pattern"; public static final String APPEND ="append"; public static final String MAX_BACKUP_INDEX ="max.backup.index"; + public static final String MAX_FILE_SIZE ="max.file.size"; public static final String ENCODING ="encoding"; public static final String COMPRESS_EXT ="compress.ext"; diff --git a/src/main/java/com/eactive/eai/common/util/Logger.java b/src/main/java/com/eactive/eai/common/util/Logger.java index c967420..89f5396 100644 --- a/src/main/java/com/eactive/eai/common/util/Logger.java +++ b/src/main/java/com/eactive/eai/common/util/Logger.java @@ -27,8 +27,9 @@ import ch.qos.logback.core.ConsoleAppender; import ch.qos.logback.core.Context; import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.RollingFileAppender; -import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; +import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; import ch.qos.logback.core.sift.AppenderFactory; +import ch.qos.logback.core.util.FileSize; import co.elastic.logging.logback.EcsEncoder; /** @@ -846,9 +847,16 @@ public class Logger implements LogKeys { rollingFileAppender.setName("FILE-" + discriminatingValue); rollingFileAppender.setFile(appenderLogDirectory + localServer + File.separator + appenderLogDirectorySub + File.separator + discriminatingValue + ".log"); - TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy<>(); + String sMaxFileSize = pmanager.getProperty(APPENDER_SIFT, MAX_FILE_SIZE, "500MB"); + + SizeAndTimeBasedRollingPolicy rollingPolicy = new SizeAndTimeBasedRollingPolicy<>(); rollingPolicy.setContext(context); - rollingPolicy.setFileNamePattern(appenderLogDirectory + localServer + File.separator + appenderLogDirectorySub + File.separator + discriminatingValue + datePattern + ".log"); + rollingPolicy.setFileNamePattern(appenderLogDirectory + localServer + File.separator + appenderLogDirectorySub + File.separator + discriminatingValue + datePattern + ".%i.log"); + if (StringUtils.isNotBlank(sMaxFileSize)) { + rollingPolicy.setMaxFileSize(FileSize.valueOf(sMaxFileSize)); + } else { + rollingPolicy.setMaxFileSize(FileSize.valueOf("500MB")); + } rollingPolicy.setParent(rollingFileAppender); rollingPolicy.setMaxHistory(maxBackupIndex); rollingPolicy.start(); @@ -1044,17 +1052,25 @@ public class Logger implements LogKeys { appender = new RollingFileAppender(); String localServer = EAIServerManager.getInstance().getLocalServerName(); - TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy(); + String sMaxFileSize = pmanager.getProperty(appenderName, MAX_FILE_SIZE, "500MB"); + + SizeAndTimeBasedRollingPolicy rollingPolicy = new SizeAndTimeBasedRollingPolicy(); if (StringUtils.isNotBlank(compressExt)){ if (compressExt.startsWith(".")) { compressExt = compressExt.substring(1); + } - rollingPolicy.setFileNamePattern( logDirectory + localServer + File.separator + logFile + datePattern + "." + compressExt); + rollingPolicy.setFileNamePattern( logDirectory + localServer + File.separator + logFile + datePattern + ".%i." + compressExt); }else{ - rollingPolicy.setFileNamePattern( logDirectory + localServer + File.separator + logFile + datePattern); + rollingPolicy.setFileNamePattern( logDirectory + localServer + File.separator + logFile + datePattern + ".%i."); } rollingPolicy.setContext( (LoggerContext) LoggerFactory.getILoggerFactory() ); rollingPolicy.setParent(appender); + if (StringUtils.isNotBlank(sMaxFileSize)) { + rollingPolicy.setMaxFileSize(FileSize.valueOf(sMaxFileSize)); + } else { + rollingPolicy.setMaxFileSize(FileSize.valueOf("500MB")); // 기본값 + } rollingPolicy.setMaxHistory(maxBackupIndex); rollingPolicy.start();