備忘録。前回の続き。
AWS SDK for Java で署名付き URL 生成 - kntmr-blog
Key Management Service (KMS) と AWS SDK for Java で、クライアントサイドで暗号化して S3 にアップロードする。
キー作成 (CMS)
事前に Key Management Service
> カスタマー管理型のキー
でキーを作成する。今回はダウンロードして復号したいので、キーのタイプには 対称 を選択する。
AWS Encryption SDK for Java - AWS Encryption SDK
暗号化に必要なライブラリを追加。これがないと AmazonS3EncryptionV2
を初期化する際に実行時エラーが発生する。
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-encryption-sdk-java</artifactId>
<version>2.0.0</version>
</dependency>
暗号化&アップロード
パターン1
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
.withCredentials(new ProfileCredentialsProvider())
.withCryptoConfiguration(new CryptoConfigurationV2()
.withCryptoMode(CryptoMode.StrictAuthenticatedEncryption))
.withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
.build();
try {
s3Encryption.putObject(bucketName, objectKey, file);
} finally {
s3Encryption.shutdown();
}
パターン2
SDK から KMS のキーを作成してアップロードするパターン。ついでにキーの削除スケジュールをリクエストする。ScheduleKeyDeletionRequest#withPendingWindowInDays
にはキーが削除可能になるまでの待機日数を指定する。(7〜30)
AWSKMS kmsClient = AWSKMSClientBuilder.standard()
.withCredentials(new ProfileCredentialsProvider())
.build();
CreateKeyRequest createKeyRequest = new CreateKeyRequest();
CreateKeyResult createKeyResult = kmsClient.createKey(createKeyRequest);
String keyId = createKeyResult.getKeyMetadata().getKeyId();
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
.withCredentials(new ProfileCredentialsProvider())
.withCryptoConfiguration(new CryptoConfigurationV2()
.withCryptoMode(CryptoMode.StrictAuthenticatedEncryption))
.withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
.build();
try {
s3Encryption.putObject(bucketName, objectKey, file);
ScheduleKeyDeletionRequest scheduleKeyDeletionRequest = new ScheduleKeyDeletionRequest()
.withKeyId(keyId)
.withPendingWindowInDays(7);
kmsClient.scheduleKeyDeletion(scheduleKeyDeletionRequest);
} finally {
s3Encryption.shutdown();
kmsClient.shutdown();
}
ダウンロード&復号
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
.withCredentials(new ProfileCredentialsProvider())
.withCryptoConfiguration(new CryptoConfigurationV2()
.withCryptoMode(CryptoMode.StrictAuthenticatedEncryption))
.withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
.build();
try {
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectKey);
s3Encryption.getObject(getObjectRequest, file);
} finally {
s3Encryption.shutdown();
}
その他
暗号化したときの keyId
以外を指定した場合、AmazonS3EncryptionV2#getObject
でエラーが発生する。(status code 400)
com.amazonaws.services.kms.model.IncorrectKeyException: The key ID in the request does not identify a CMK that can perform this operation.
暗号化してアップロードしたファイルは AmazonS3#getObject
でもダウンロードできるが、暗号化されているため開けない。マネジメントコンソールからダウンロードした場合も同様に開けない。
暗号化したファイルのコピーや削除では keyId
の指定は不要で、AmazonS3#copyObject
or AmazonS3.deleteObject
が使える。もちろん、暗号化したままコピーされる。