From 202261d1e622be04f5877c7ce6338e910c2d6a4b Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 26 Sep 2025 17:59:58 +0900 Subject: [PATCH] =?UTF-8?q?Revert=20"PTL=5FUSER=20=EC=95=94=ED=98=B8?= =?UTF-8?q?=ED=99=94=20=EC=A0=81=EC=9A=A9,=20SafeDB=20Wrapper=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 790f9092fe1f8c6fc39561a58699487550452695. --- .gitignore | 1 - build.gradle | 19 ++-- .../portal/portaluser/entity/PortalUser.java | 15 +-- .../eactive/ext/kjb/safedb/SafeDBBroker.java | 19 ---- .../eactive/ext/kjb/safedb/SafeDBColumns.java | 51 ---------- .../eactive/ext/kjb/safedb/SafeDBFaker.java | 73 -------------- .../kjb/safedb/SafeDBMNotRnnoConverter.java | 81 ---------------- .../eactive/ext/kjb/safedb/SafeDBWrapper.java | 91 ------------------ .../kjb/safedb/SafeDBWrapperException.java | 46 --------- .../kjb/safedb/SafeDBWrapperSdkException.java | 18 ---- .../kjb/safedb/test/SafeDbWrapperTest.java | 95 ------------------- 11 files changed, 11 insertions(+), 498 deletions(-) delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBBroker.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBColumns.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBFaker.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBMNotRnnoConverter.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapper.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperException.java delete mode 100644 src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperSdkException.java delete mode 100644 src/test/java/com/eactive/ext/kjb/safedb/test/SafeDbWrapperTest.java diff --git a/.gitignore b/.gitignore index 2f40306..6b285d2 100644 --- a/.gitignore +++ b/.gitignore @@ -71,7 +71,6 @@ local.properties .idea # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -*.iml # User-specific stuff .idea/**/workspace.xml diff --git a/build.gradle b/build.gradle index 207dbfb..de917f6 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,12 @@ def hibernateVersion = "5.6.15.Final" def generatedJavaDir = "$buildDir/generated/java" def generatedTestJavaDir = "$buildDir/generated-test/java" +repositories { + maven { + url "${nexusUrl}/repository/maven-public/" + allowInsecureProtocol = true + } +} java { toolchain { @@ -106,11 +112,6 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.8.2' - - - // 광주은행 safedb 용 임시 라이브러리 - compileOnly(fileTree(dir: "tmp/safedb", include: ["*.jar"])) -// implementation(fileTree(dir: "tmp/safedb", include: ["*.jar"])) } test { @@ -186,11 +187,3 @@ eclipse { tasks.named('eclipse').configure { finalizedBy 'compileJava', 'compileTestJava' } - -idea { - module { - generatedSourceDirs.add(file(generatedJavaDir)) - generatedSourceDirs.add(file(generatedTestJavaDir)) - } - -} \ No newline at end of file diff --git a/src/main/java/com/eactive/apim/portal/portaluser/entity/PortalUser.java b/src/main/java/com/eactive/apim/portal/portaluser/entity/PortalUser.java index 6253802..1c63d96 100644 --- a/src/main/java/com/eactive/apim/portal/portaluser/entity/PortalUser.java +++ b/src/main/java/com/eactive/apim/portal/portaluser/entity/PortalUser.java @@ -5,14 +5,13 @@ import com.eactive.apim.portal.portalorg.entity.PortalOrg; import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.ApprovalStatus; import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.RoleCode; import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.UserStatus; -import com.eactive.ext.kjb.safedb.SafeDBMNotRnnoConverter; +import java.io.Serializable; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Comment; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; -import java.io.Serializable; import java.time.LocalDateTime; @Data @@ -29,9 +28,8 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e @GeneratedValue(generator = "uuid-gen", strategy = GenerationType.IDENTITY) private String id; - @Column(name = "login_id", length = 200, nullable = false) + @Column(name = "login_id", length = 32, nullable = false) @Comment("로그인ID") - @Convert(converter = SafeDBMNotRnnoConverter.class) private String loginId; @Column(name = "password_hash", length = 60) @@ -42,19 +40,16 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e @Comment("사용자이름") private String userName; - @Column(name = "phone_number", length = 50) + @Column(name = "phone_number", length = 12) @Comment("전화번호") - @Convert(converter = SafeDBMNotRnnoConverter.class) private String phoneNumber; - @Column(name = "mobile_number", length = 50) + @Column(name = "mobile_number", length = 20) @Comment("휴대폰 번호") - @Convert(converter = SafeDBMNotRnnoConverter.class) private String mobileNumber; - @Column(name = "email_addr", length = 200) + @Column(name = "email_addr", length = 30) @Comment("이메일주소") - @Convert(converter = SafeDBMNotRnnoConverter.class) private String emailAddr; @ManyToOne(fetch = FetchType.EAGER) diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBBroker.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBBroker.java deleted file mode 100644 index 187d450..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBBroker.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -import java.lang.reflect.InvocationTargetException; - -public abstract class SafeDBBroker extends SafeDBFaker{ - private Object instance; - - protected void initialize() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class clazz = Class.forName("com.initech.safedb.SimpleSafeDB"); - instance = clazz.getMethod("getInstance").invoke(null); - } - - protected Object methodInvoke(String methodName, Class[] paramTypes, Object[] params) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - if (instance == null) { - throw new IllegalStateException("SafeDBBroker is not initialized."); - } - return instance.getClass().getMethod(methodName, paramTypes).invoke(instance, params); - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBColumns.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBColumns.java deleted file mode 100644 index a4d6b73..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBColumns.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -public enum SafeDBColumns { - RNNO("RNNO"), - PSWD("PSWD"), - NOT_RNNO("NOT_RNNO"),; - - - private final String value; - - SafeDBColumns (String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public static boolean contains(String test) { - for (SafeDBColumns c : SafeDBColumns.values()) { - if (c.name().equals(test)) { - return true; - } - } - return false; - } - - public static boolean isEqualsIgnoreCase(SafeDBColumns column, String test) { - if (column == null || test == null) { - return false; - } - return column.getValue().equalsIgnoreCase(test); - } - - public static SafeDBColumns fromString(String text) { - for (SafeDBColumns b : SafeDBColumns.values()) { - if (b.name().equalsIgnoreCase(text)) { - return b; - } - } - throw new IllegalArgumentException("No constant with text " + text + " found"); - } - - - public boolean isEqualsIgnoreCase(String test) { - if (test == null) { - return false; - } - return this.value.equalsIgnoreCase(test); - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBFaker.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBFaker.java deleted file mode 100644 index b174152..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBFaker.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; -import java.security.MessageDigest; - -/** - * SafeDBFaker provides a fake encryption method for testing purposes when the real SafeDB library is not available. - */ -public abstract class SafeDBFaker { - private static final String AES_256_KEY = "1234567890123456" + "1234567890123456"; - - - public String fakeEncrypt(String userId, String table, String column, String data) { - if (SafeDBColumns.PSWD.isEqualsIgnoreCase(column)) { - // SHA256 + Base64 인코딩된 가짜 비밀번호 반환 - return sha256Base64(data); - } else { - // AES256 암호화된 가짜 데이터 반환 - return aes256Encrypt(data); - } - } - - public String fakeDecrypt(String userId, String table, String column, String data) { - if (SafeDBColumns.PSWD.isEqualsIgnoreCase(column)) { - // 비밀번호는 복호화하지 않음 - throw new UnsupportedOperationException("Password decryption is not supported."); - } else { - // AES256 복호화된 가짜 데이터 반환 - return aes256Decrypt(data); - } - } - - - private String sha256Base64(String data) { - try { - MessageDigest digest = java.security.MessageDigest.getInstance("SHA-256"); - - // JVM 옵션을 따라가기 위해 캐릭터셋을 명시 하지 않음. - byte[] hash = digest.digest(data.getBytes()); - - return java.util.Base64.getEncoder().encodeToString(hash); - } catch (Exception e) { - throw new RuntimeException("Error generating SHA-256 hash", e); - } - } - - // AES256 암호화 - private String aes256Encrypt(String data) { - try { - Cipher cipher = javax.crypto.Cipher.getInstance("AES"); - SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(AES_256_KEY.getBytes(), "AES"); - cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec); - byte[] encrypted = cipher.doFinal(data.getBytes()); - return java.util.Base64.getEncoder().encodeToString(encrypted); - } catch (Exception e) { - throw new RuntimeException("Error during AES encryption", e); - } - } - - private String aes256Decrypt(String encryptedData) { - try { - Cipher cipher = javax.crypto.Cipher.getInstance("AES"); - SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(AES_256_KEY.getBytes(), "AES"); - cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec); - byte[] decodedBytes = java.util.Base64.getDecoder().decode(encryptedData); - byte[] decrypted = cipher.doFinal(decodedBytes); - return new String(decrypted); - } catch (Exception e) { - throw new RuntimeException("Error during AES decryption", e); - } - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBMNotRnnoConverter.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBMNotRnnoConverter.java deleted file mode 100644 index d04f77f..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBMNotRnnoConverter.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; - -@Converter -@Slf4j -public class SafeDBMNotRnnoConverter implements AttributeConverter { - /** - * 암호화 - * @param attribute the entity attribute value to be converted - * @return - */ - @Override - public String convertToDatabaseColumn(String attribute) { - log.debug("DB 암호화 #1 - {} / {}", attribute, SafeDBColumns.NOT_RNNO); - - String originalAttribute = attribute; - if (StringUtils.isNotEmpty(attribute)) { - SafeDBWrapper safeDBWrapper = SafeDBWrapper.getInstance(); - attribute = safeDBWrapper.encryptNotRnno(attribute); - } - - log.debug("DB 암호화 #2 : {} -> {}", originalAttribute, attribute); - - return attribute; - } - - /** - * 복호화 - * @param dbData the data from the database column to be - * converted - * @return - */ - @Override - public String convertToEntityAttribute(String dbData) { - log.debug("DB 복호화 #1 - {} / {}", dbData, SafeDBColumns.NOT_RNNO); - - String dbDataOriginal = dbData; - if (StringUtils.isNotEmpty(dbData)) { - if (this.isEncrypted(dbData)) { - SafeDBWrapper safeDBWrapper = SafeDBWrapper.getInstance(); - dbData = safeDBWrapper.decryptNotRnno(dbData); - } else { - log.debug("DB 복호화 경고: Base64 형식이 아님. 복호화하지 않고 원본 반환. dbData={}", dbData); - } - } - - log.debug("DB 복호화 #2 : {} -> {}", dbDataOriginal, dbData); - - return dbData; - } - - /** - * 암호화 여부 확인(base64 인코딩 여부로 판단, 또는 0-9, - 로 구성된 경우 암호화 되지 않은 걸로 판단(연락처)) - * @param data - * @return - */ - private boolean isEncrypted(String data) { - if (StringUtils.isEmpty(data)) { - return false; - } - - data = data.trim(); - - // Base64 형식 체크 - if (SafeDBWrapper.isBase64(data)) { - return true; - } - - // 숫자, - 로만 구성된 경우 암호화 되지 않은 걸로 판단 (ex: 연락처) - if (data.matches("^[0-9-]+$")) { - return false; - } - - return false; - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapper.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapper.java deleted file mode 100644 index ea6530c..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapper.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -public class SafeDBWrapper extends SafeDBBroker { - private static SafeDBWrapper instance; - private boolean isRealSafeDB = false; - - - public static SafeDBWrapper getInstance() { - if ( instance == null ) { - synchronized ( SafeDBWrapper.class ) { - if ( instance == null ) { - instance = new SafeDBWrapper(); - } - } - } - return instance; - } - - public static boolean isBase64(String str) { - if (str == null || str.isEmpty()) { - return false; - } - String base64Pattern = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"; - return str.matches(base64Pattern); - } - - - private SafeDBWrapper() throws SafeDBWrapperException { - synchronized ( SafeDBWrapper.class ) { - // "com.initech.safedb.SimpleSafeDB" 클래스 존재 여부 확인 - try { - Class.forName("com.initech.safedb.SimpleSafeDB"); - isRealSafeDB = true; // 클래스가 존재하면 true로 설정 - } catch (ClassNotFoundException e) { - isRealSafeDB = false; // 클래스가 존재하지 않으면 false로 설정 - } catch (Exception e) { - throw new SafeDBWrapperException(("[SafeDBWrapper] Classloader error: " + e.getMessage()), e); - } - - if (isRealSafeDB) { - try { - super.initialize(); - } catch (Exception e) { - throw new SafeDBWrapperException("[SafeDBWrapper] Initialization error: " + e.getMessage(), e); - } - } - } - } - - - public String encrypt(String userId, String table, String column, String data) throws SafeDBWrapperSdkException { - if (isRealSafeDB) { - try { - return (String) super.methodInvoke("encrypt", - new Class[]{String.class, String.class, String.class, String.class}, - new Object[]{userId, table, column, data}); - } catch (Exception e) { - throw new SafeDBWrapperSdkException("[SafeDBWrapper] Encrypt error: " + e.getMessage(), e); - } - } else { - return super.fakeEncrypt(userId, table, column, data); - } - } - - public String encryptNotRnno(String data) throws SafeDBWrapperSdkException { - return this.encrypt("SAFEDB", "SAFEDB.POLICY", "NOT_RNNO", data); - } - - - public String decrypt(String userId, String table, String column, String data) throws SafeDBWrapperSdkException { - if (isRealSafeDB) { - try { - return (String) super.methodInvoke("decrypt", - new Class[]{String.class, String.class, String.class, String.class}, - new Object[]{userId, table, column, data}); - } catch (Exception e) { - throw new SafeDBWrapperException("[SafeDBWrapper] Decrypt error: " + e.getMessage(), e); - } - } else { - return super.fakeDecrypt(userId, table, column, data); - } - } - - public String decryptNotRnno(String data) throws SafeDBWrapperSdkException { - return this.decrypt("SAFEDB", "SAFEDB.POLICY", "NOT_RNNO", data); - } - - public boolean isRealSafeDB() { - return isRealSafeDB; - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperException.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperException.java deleted file mode 100644 index e28c846..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperException.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -public class SafeDBWrapperException extends RuntimeException { - private Exception cause; - private int errcode; - - - public SafeDBWrapperException() { - } - - - public SafeDBWrapperException(String message) { - super(message); - } - - public SafeDBWrapperException(String message, Throwable cause) { - super(message, cause); - } - - public SafeDBWrapperException(String message, Exception cause) { - super(message); - this.cause = cause; - } - - public SafeDBWrapperException(int errcode, String message) { - super(message); - this.errcode = errcode; - } - - public SafeDBWrapperException(String errcode, String message) { - super(message); - this.errcode = new Integer(errcode); - } - - public Throwable getCause() { - return this.cause; - } - - public String getMessage() { - return this.cause != null ? super.getMessage() + "\n caused by [ " + this.cause.getMessage() + " ]" : super.getMessage(); - } - - public int getErrorCode() { - return this.errcode; - } -} diff --git a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperSdkException.java b/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperSdkException.java deleted file mode 100644 index 750da82..0000000 --- a/src/main/java/com/eactive/ext/kjb/safedb/SafeDBWrapperSdkException.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.eactive.ext.kjb.safedb; - -public class SafeDBWrapperSdkException extends SafeDBWrapperException { - public SafeDBWrapperSdkException(Exception ex) { - super(ex.getMessage(), ex); - } - - public SafeDBWrapperSdkException(String message) { - super(message); - } - - public SafeDBWrapperSdkException(String message, Exception ex) { - super(message, ex); - } - - public SafeDBWrapperSdkException() { - } -} diff --git a/src/test/java/com/eactive/ext/kjb/safedb/test/SafeDbWrapperTest.java b/src/test/java/com/eactive/ext/kjb/safedb/test/SafeDbWrapperTest.java deleted file mode 100644 index 37509e8..0000000 --- a/src/test/java/com/eactive/ext/kjb/safedb/test/SafeDbWrapperTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.eactive.ext.kjb.safedb.test; - -import com.eactive.ext.kjb.safedb.SafeDBWrapper; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class SafeDbWrapperTest { - - @Test - public void faceSafeDBTest() { - log("FakeSafeDBWrapper Length Validation Start"); - - SafeDBWrapper wrapper; - try { - wrapper = SafeDBWrapper.getInstance(); - } catch (Exception e) { - // classloader 에러인지 initialization 에러인지 구분 - if (e.getMessage().contains("Classloader error")) { - throw new RuntimeException("SafeDBWrapper classloader error: " + e.getMessage(), e); - } else { - // initialization 에러(로컬에서는 동작하지 않는다 = 정상 처리) - log("SafeDBWrapper initialization error (expected in local environment): " + e.getMessage()); - return; - } - } - - if (wrapper.isRealSafeDB()) { - log("This test is for FakeSafeDBWrapper only. Skipping test."); - return; - } - - - for (int len = 1; len <= 255; len++) { - String originalData = repeat("A", len); // JDK8 호환 반복 문자열 - try { - // 암호화 (Base64 인코딩 결과 가정) - String encryptedData = wrapper.encrypt("userId", "tableName", "columnName", originalData); - - // 예상 암호문 길이 계산 - int expectedLen = getExpectedCipherLength(len, true); - - // 복호화 - String decryptedData = wrapper.decrypt("userId", "tableName", "columnName", encryptedData); - assertEquals(originalData, decryptedData, "Decrypted data does not match original at plain length=" + len); - - // 로그 출력 - log(String.format("Plain=%3d, Encrypted=%3d, Expected=%3d %s", - len, encryptedData.length(), expectedLen, - (encryptedData.length() == expectedLen ? "✔" : "❌"))); - - // 검증 - // "Length mismatch at plain length=" - assertEquals(len, expectedLen, encryptedData.length()); - - - // 암복호화 로그 출력 - log(String.format("Original: %s", originalData) + - String.format("\nEncrypted: %s", encryptedData) + - String.format("\nDecrypted: %s", decryptedData) + "\n"); - - - } catch (Exception e) { - throw new RuntimeException("Error at plain length=" + len, e); - } - } - } - - /** - * 암호문 예상 길이 계산 (AES/SEED/ARIA CBC 기준, PKCS5Padding) - */ - private int getExpectedCipherLength(int plainLength, boolean base64Encoding) { - int blockSize = 16; - int paddedLength = ((plainLength / blockSize) + 1) * blockSize; - - if (base64Encoding) { - return (int) (Math.ceil(paddedLength / 3.0) * 4); - } else { - return paddedLength; - } - } - - /** JDK8에서 문자열 반복 (String.repeat 대체) */ - private String repeat(String s, int count) { - StringBuilder sb = new StringBuilder(s.length() * count); - for (int i = 0; i < count; i++) { - sb.append(s); - } - return sb.toString(); - } - - private void log(String message) { - System.out.println(message); - } -}