備忘録。前回の続き。
AWS SDK for Java で署名付き URL 生成 - kntmr-blog
Key Management Service (KMS) と AWS SDK for Java で、クライアントサイドで暗号化して S3 にアップロードする。
キー作成 (CMS)
事前に Key Management Service
> カスタマー管理型のキー
でキーを作成する。今回はダウンロードして復号したいので、キーのタイプには 対称 を選択する。
AWS Encryption SDK
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
が使える。もちろん、暗号化したままコピーされる。