AWS Key Management Service (KMS) is a managed service that manages the encryption keys used to encrypt your data. KMS can handle data securely by using an encryption method called envelope encryption.
I have summarized the Java implementation examples of envelope encryption because there are few Japanese documents.
Roughly speaking
It is a mechanism to make it secure by using properly.
A common encryption method protects plaintext data by encrypting it with some key. At this time, if this key is stolen together with the data, the code will be decrypted and the raw data will be visible. Therefore, the idea of envelope encryption is to protect the data more strongly by further encrypting the key that encrypted the data with another key.
Data encryption using KMS can be achieved by the following flow.
--Generate a master key on the KMS console screen --Generate data key from master key --Encrypt plaintext data using a data key --Encrypt data key --Keep your encrypted data key and encrypted data in a safe place
The following is an implementation example in Java for implementing envelope encryption.
We will assume that the master key has been generated in advance from the KMS console screen. For the master key generation procedure, see AWS Manual or [Developers.IO](http: / Please refer to articles such as /dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-aws-relearning-key-management-service/).
AWS provides an SDK for using KMS. Here is an example of using the library via Gradle. Add the following dependency to build.gradle
.
dependencies {
compile "com.amazonaws:aws-java-sdk-kms:1.11.202"
}
First, create an instance of ʻAWSKMSClient` using the AWS access key and secret key.
BasicAWSCredentials credentials = new BasicAWSCredentials("accessKey...", "SecretKey...");
AWSKMSClient client = (AWSKMSClient) AWSKMSClientBuilder.standard()
.withRegion("ap-northeast-1")
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
Generate a data key using the generated client. You can get the data key by creating an instance of GenerateDataKeyRequest
and doing generateDataKey
by specifying the KeyId as the ARN of the master key generated from the KMS console.
GenerateDataKeyRequest generateDataKeyRequest = new GenerateDataKeyRequest()
.withKeyId("arn:aws:kms:...")
.withKeySpec(DataKeySpec.AES_128);
GenerateDataKeyResult dataKeyResult = client.generateDataKey(generateDataKeyRequest);
Encrypt plaintext data using the generated data key. Here, AES is used for encryption, but you can use any encryption method.
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,
new SecretKeySpec(dataKeyResult.getPlaintext().array(), "AES"));
String decriptedText = Base64.getEncoder()
.encodeToString(cipher.doFinal("plainText...".getBytes()));
} catch (Exception e) {
// do something.
}
The generated decriptedText
and the encrypted data key (you can get the encrypted one withdataKeyResult.getCiphertextBlob ()
) are encoded in Base64, copied to a yaml file, etc. and saved. Let's go.
Next is the procedure for decrypting encrypted data. Decryption is done by generating a decryptRequest
from the encrypted data key.
DecryptRequest decryptRequest = new DecryptRequest()
.withCiphertextBlob(ByteBuffer.wrap(Base64.getDecoder().decode("decryptedDatakey...".getBytes())));
ByteBuffer plainTextKey = client.decrypt(decryptRequest).getPlaintext();
With the above steps, you have successfully converted the encrypted data key back to the plaintext data key. Then, use the obtained data key to decrypt the encrypted data.
byte[] decodeBase64src = Base64.getDecoder().decode("decryptedText...");
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, plainTextKey);
String plainText = new String(cipher.doFinal(decodeBase64src));
} catch (Exception e) {
// do something.
}
Discard the extracted plaintext data key (plainTextKey
) immediately.
plainTextKey.clear();
-What is AWS Key Management Service -AWS Key Management Service Concept -Reintroduction to AWS-Amazon KMS