-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Secure Key Manager
-
기밀 데이터(데이터베이스 접속 정보, 앱키, 비밀번호 등), 대칭키, 비대칭키와 같이 애플리케이션 서버에 저장할 경우 보안 위험에 노출될 수 있는 데이터를 중앙 집중적으로 안전하게 관리하고, 인증을 통과한 클라이언트만 접근할 수 있게 제어하는 서비스입니다.
-
정보보호관리체계(ISMS) 인증 심사의 요구사항인 개인정보 암호화 키를 물리적으로 분리 보관하여야 한다는 요건을 만족시키기 위한 고객사/개발사를 위한 서비스이다.
-
공개 키 암호 표준 PKCS(Public-Key Cyptography Standard) RSA 시큐리티에서 정한, 공개 키 암호에 대한 사용 방식에 대한 표준 프로토콜을 따르는 서비스
-
Personal Information Exchange Syntax Standard 개인 정보 교환 표준 사용자의 개인키, 인증 등의 저장과 교환을 위한 포맷을 설명하는 파일이다.
-
확장자는 .p12, .pfx 를 가진다.
구조
- 루트키와 시스템 키 라는 두개의 암호키를 내부적으로 사용한다.
- 루트키는 시스템키를 보호하기 위해 사용
- 시스템키는 사용자 데이터를 보호하기 위해 사용
기능
-
데이터 관리
- 기밀 데이터 등록, 관리, 조회
- 대칭키 생성, 관리, 회전, 데이터 암호화, 복호화, 조회
- 비대칭키 생성, 관리, 회전, 데이터 서명, 데이터 검증, 조회
-
데이터 접근 제어
- 클라이언트 IPv4 주소를 사용한 데이터 접근 제어
- 클라이언트 MAC 주소를 사용한 데이터 접근 제어
- 클라이언트 인증서를 사용한 데이터 접근 제어
-
승인기능
- 데이터, 데이터 접근 제어의 변경을 승인자, 요청자로 나누어 관리
사용
1.1 인증서 관리
1.2 인증서 등록
1.3 인증서 파일
인증서는 .p12 파일로 다운로드 된다.
이 파일은 PKCS #12 형식을 사용하는 인증서 입니다.
이 인증서는 프로젝트의 resource 폴더에 위치 시키면 됩니다.
1.4 키 관리
1.5 키 추가
1.6 키 상세 정보
2. 프로젝트 로직 설정
2.1 DTO 클래스
@Getter
public class KeyResponseDto {
private Header header;
private Body body;
@Getter
@NoArgsConstructor
public static class Body {
private String secret;
}
@Getter
@NoArgsConstructor
public static class Header {
private Integer resultCode;
private String resultMessage;
private boolean isSuccessful;
}
}###2.2 API
기밀 데이터 조회 api
조회 코드
@Configuration
public class KeyConfig {
private final KeyProperties keyProperties;
@Autowired
public KeyConfig(KeyProperties keyProperties) {
this.keyProperties = keyProperties;
}
public String keyStore(String keyId) {
try {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
InputStream result = new ClassPathResource("my-books.p12").getInputStream();
clientStore.load(result, keyProperties.getPassword().toCharArray());
SSLContext sslContext = SSLContextBuilder.create()
.setProtocol("TLS")
.loadKeyMaterial(clientStore, keyProperties.getPassword().toCharArray())
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
RestTemplate restTemplate = new RestTemplate(requestFactory);
URI uri = UriComponentsBuilder
.fromUriString(keyProperties.getUrl())
.path(keyProperties.getPath())
.encode()
.build()
.expand(keyProperties.getAppKey(), keyId)
.toUri();
return Objects.requireNonNull(restTemplate.exchange(uri,
HttpMethod.GET,
new HttpEntity<>(headers),
KeyResponseDto.class)
.getBody())
.getBody()
.getSecret();
} catch (KeyStoreException | IOException | CertificateException
| NoSuchAlgorithmException
| UnrecoverableKeyException
| KeyManagementException e) {
throw new KeyMangerException(e.getMessage());
}
}
}2.3 키 복호화 하여 사용
키값을 properties파일에 저장한다
Properties에 있는 키값을 가지고 있는 클래스를 빈으로 등록
keyConfig.keyStore(databaseProperties.getUrl())를 호출하여 실제 값을 복호화 하여 가져온다
@Configuration
public class DatabaseConfig {
private final KeyConfig keyConfig;
private final DatabaseProperties databaseProperties;
@Autowired
public DatabaseConfig(KeyConfig keyConfig, DatabaseProperties databaseProperties) {
this.keyConfig = keyConfig;
this.databaseProperties = databaseProperties;
}
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl(keyConfig.keyStore(databaseProperties.getUrl()));
dataSource.setUsername(keyConfig.keyStore(databaseProperties.getUserName()));
dataSource.setPassword(keyConfig.keyStore(databaseProperties.getPassword()));
dataSource.setInitialSize(databaseProperties.getInitialSize());
dataSource.setMaxTotal(databaseProperties.getMaxTotal());
dataSource.setMinIdle(databaseProperties.getMinIdle());
dataSource.setMaxIdle(databaseProperties.getMaxIdle());
dataSource.setMaxWaitMillis(databaseProperties.getMaxWait());
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTestWhileIdle(true);
return dataSource;
}Reference
https://docs.nhncloud.com/ko/Security/Secure%20Key%20Manager/ko/overview/
Metadata
Metadata
Assignees
Labels
Type
Projects
Status









