개요
AWS Key Management Service (KMS)는 AWS에서 제공하는 완전 관리형 암호화 키 관리 서비스로, 사용자는 암호화 키를 생성하고 암복호화를 통해 데이터를 관리합니다.
Customer Master Key (CMK)는 KMS에서 사용되는 주요 암호화 키로, 데이터 암호화 및 복호화에 사용되며, 사용자가 직접 관리하는 고객 마스터 키(CMK) 외에도, AWS 관리 키(AWS Managed Key)와 AWS KMS가 자동으로 생성하는 및 관리하는 서비스 전용 키(Service-specific key) 등 방법이 존재합니다.
Customer Master Key (CMK)는 KMS에서 사용되는 주요 암호화 키로, 데이터 암호화 및 복호화에 사용되며, 사용자가 직접 관리하는 고객 마스터 키(CMK) 외에도, AWS 관리 키(AWS Managed Key)와 AWS KMS가 자동으로 생성하는 및 관리하는 서비스 전용 키(Service-specific key) 등 방법이 존재합니다.
KMSUtils
AWS KMS를 사용하여 데이터를 암호화하고 복호화하는 유틸리티 클래스를 작성해보겠습니다.
encrypt 메서드와 decrypt 메서드를 가진 KmsUtils 클래스를 작성하며, encrypt 메서드는 주어진 텍스트를 AWS KMS를 사용하여 암호화하고, decrypt 메서드는 암호화된 텍스트를 AWS KMS를 사용하여 복호화합니다.
이 유틸을 사용하여 데이터베이스 연결 정보를 프로퍼티 파일에 저장할 때 비밀번호를 암호화하고, 애플리케이션에서는 복호화된 비밀번호를 사용하여 데이터베이스에 연결하여 데이터 유출의 위험을 최소화하며 안전하게 보호할 수 있습니다.
[AWS] CMK 생성
AWS Key Management Service 고객 관리형 키 생성
[Spring] 프로젝트 세팅
1. build.gradle 의존성 추가
implementation 'com.amazonaws:aws-java-sdk-kms:1.12.711'
implementation 'com.amazonaws:aws-java-sdk-core:1.12.711'
2. application-profile.yml 키 등록
aws:
kms:
key: {key-id}
3. KmsUtils 작성
@Slf4j
@Component
public class KmsUtils {
@Value("${aws.kms.key}")
private String key;
private static final Regions REGIONS = Regions.AP_NORTHEAST_2;
private static final EncryptionAlgorithmSpec ALGORITHM = EncryptionAlgorithmSpec.SYMMETRIC_DEFAULT;
public String encrypt(String text) {
AWSKMS kmsClient = AWSKMSClientBuilder.standard()
.withRegion(REGIONS)
.withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
.build();
EncryptRequest request = new EncryptRequest();
request.withKeyId(key);
request.withPlaintext(ByteBuffer.wrap(text.getBytes(StandardCharsets.UTF_8)));
request.withEncryptionAlgorithm(ALGORITHM);
byte[] encryptBytes = kmsClient.encrypt(request).getCiphertextBlob().array();
return Base64.encodeBase64String(encryptBytes);
}
public String decrypt(String encryptText) {
AWSKMS kmsClient = AWSKMSClientBuilder.standard()
.withRegion(REGIONS)
.withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
.build();
DecryptRequest request = new DecryptRequest();
request.withKeyId(key);
request.withCiphertextBlob(ByteBuffer.wrap(Base64.decodeBase64(encryptText)));
request.withEncryptionAlgorithm(ALGORITHM);
byte[] textBytes = kmsClient.decrypt(request).getPlaintext().array();
return new String(textBytes);
}
}
[Junit5] 테스트
@ExtendWith(MockitoExtension.class)
class KmsUtilsTest {
final String KEY = "kms-key";
final Regions REGIONS = Regions.AP_NORTHEAST_2;
final EncryptionAlgorithmSpec ALGORITHM = EncryptionAlgorithmSpec.SYMMETRIC_DEFAULT;
@Test
@DisplayName("암복호화 테스트")
void encrypt() {
// given
final String plaintext = "Hello, World!";
// when
AWSKMS kmsClient = AWSKMSClientBuilder.standard()
.withRegion(REGIONS)
.withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
.build();
EncryptRequest encryptRequest = new EncryptRequest();
encryptRequest.withKeyId(KEY);
encryptRequest.withPlaintext(ByteBuffer.wrap(plaintext.getBytes(StandardCharsets.UTF_8)));
encryptRequest.withEncryptionAlgorithm(ALGORITHM);
byte[] cipherBytes = kmsClient.encrypt(encryptRequest).getCiphertextBlob().array();
String encryptText = Base64.encodeBase64String(cipherBytes);
DecryptRequest decryptRequest = new DecryptRequest();
decryptRequest.withKeyId(KEY);
decryptRequest.withCiphertextBlob(ByteBuffer.wrap(Base64.decodeBase64(encryptText)));
decryptRequest.withEncryptionAlgorithm(ALGORITHM);
byte[] textBytes = kmsClient.decrypt(decryptRequest).getPlaintext().array();
String decryptText = new String(textBytes);
System.out.println("plaint text : " + plaintext);
System.out.println("encrypt text : " + encryptText);
System.out.println("decrypt text : " + decryptText);
// then
assertEquals(plaintext, decryptText);
}
}
이번 글에서는 AWS Key Management Service (KMS)를 활용하여 데이터를 안전하게 암호화하고 복호화하는 유틸리티 클래스를 만들어보았습니다.
테스트 결과를 통해 이 클래스가 원활하게 작동함을 확인할 수 있었으며, 프로퍼티 파일과 같은 중요한 정보를 안전하게 암호화하고 관리할 수 있습니다. :)