CryptoModuleManager 기반 암호화모듈 진단/암복호화 테스트 관리 API 추가

/manage/crypto 하위에 등록된 암호화모듈 목록/단건 조회, DYNAMIC 키
전략(KeyDerivationStrategy) 로드 상태 확인, 동적 키 캐시 키 목록 조회,
Base64 기반 암복호화 라운드트립 테스트 엔드포인트를 제공한다.
원본 암호키(encKeyHex/decKeyHex/ivHex)는 응답에 포함하지 않는다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
curry772
2026-07-21 14:59:09 +09:00
parent c118c88dce
commit 98d815e659
9 changed files with 1218 additions and 0 deletions
@@ -0,0 +1,28 @@
package com.eactive.eai.common.security;
import lombok.Data;
/**
* CryptoModuleManager 진단정보 DTO.
*
* 원본 암호키(encKey/decKey) 및 IV는 절대 포함하지 않는다. 메타데이터와
* 키 도출 전략(KeyDerivationStrategy) 로드 상태만 담는다.
*/
@Data
public class CryptoModuleDiagnosticDTO {
String cryptoName;
String cryptoDesc;
String algType;
String cipherMode;
String padding;
boolean hasIv;
String keySourceType;
String keyDerivStrategy;
boolean strategyLoaded;
String strategyClassName;
String strategyLoadError;
String cacheYn;
Integer cacheTtlSec;
String useYn;
}
@@ -1,5 +1,6 @@
package com.eactive.eai.common.security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -153,6 +154,58 @@ public class CryptoModuleManager implements Lifecycle {
return buildExtension(vo, iv, derivedKey.getEncKey(), derivedKey.getDecKey());
}
/**
* 등록된 전체 암호화모듈의 진단정보를 반환한다.
* 원본 키(encKey/decKey/ivHex)는 포함하지 않는다.
*/
public List<CryptoModuleDiagnosticDTO> describeAll() {
List<CryptoModuleDiagnosticDTO> result = new ArrayList<>();
for (String cryptoName : configMap.keySet()) {
result.add(describe(cryptoName));
}
return result;
}
/**
* 단일 암호화모듈의 진단정보를 반환한다. DYNAMIC 키 방식인 경우 resolveStrategy를 통해
* 전략 클래스 로드 성공 여부를 함께 확인한다. 원본 키(encKey/decKey/ivHex)는 포함하지 않는다.
*/
public CryptoModuleDiagnosticDTO describe(String cryptoName) {
CryptoModuleConfigVO vo = getVO(cryptoName);
CryptoModuleDiagnosticDTO dto = new CryptoModuleDiagnosticDTO();
dto.setCryptoName(vo.getCryptoName());
dto.setCryptoDesc(vo.getCryptoDesc());
dto.setAlgType(vo.getAlgType());
dto.setCipherMode(vo.getCipherMode());
dto.setPadding(vo.getPadding());
dto.setHasIv(vo.getIvHex() != null);
dto.setKeySourceType(vo.getKeySourceType());
dto.setCacheYn(vo.getCacheYn());
dto.setCacheTtlSec(vo.getCacheTtlSec());
dto.setUseYn(vo.getUseYn());
if (!"STATIC".equalsIgnoreCase(vo.getKeySourceType()) && vo.getKeyDerivStrategy() != null) {
dto.setKeyDerivStrategy(vo.getKeyDerivStrategy());
try {
KeyDerivationStrategy strategy = resolveStrategy(vo.getKeyDerivStrategy());
dto.setStrategyLoaded(true);
dto.setStrategyClassName(strategy.getClass().getName());
} catch (Exception e) {
dto.setStrategyLoaded(false);
dto.setStrategyLoadError(e.getMessage());
}
}
return dto;
}
/**
* 동적 키 캐시에 존재하는 캐시 키 목록을 반환한다. (전략별 buildCacheKey 결과이며, 원본 키 값이 아니다)
*/
public List<String> listDynamicCacheKeys() {
return new ArrayList<>(dynamicKeyCache.keySet());
}
private CryptoModuleConfigVO getVO(String cryptoName) {
CryptoModuleConfigVO vo = configMap.get(cryptoName);
if (vo == null) {