AWS SDK for Java を使用したお客様が用意した暗号化キーによるサーバー側の暗号化の指定 - Amazon Simple Storage Service

AWS SDK for Java を使用したお客様が用意した暗号化キーによるサーバー側の暗号化の指定

次の例では、オブジェクト用にお客様が用意したキーによるサーバー側の暗号化 (SSE-C) をリクエストする方法を示します。この例は以下のオペレーションを実行します。各オペレーションでは、SSE-C 関連ヘッダーをリクエストで指定する方法を示します。

  • Put object — オブジェクトをアップロードし、顧客が用意した暗号キーによるサーバー側の暗号化をリクエストします。

  • Get object — 前のステップでアップロードしたオブジェクトをダウンロードします。リクエストでは、オブジェクトのアップロード時に指定したのと同じ暗号化情報を指定します。Amazon S3 は、オブジェクトを復号して返すために、この情報を必要とします。

  • Get object metadata — オブジェクトのメタデータを取得します。オブジェクトの作成時に使用したのと同じ暗号化情報を指定します。

  • Copy object — 前にアップロードしたオブジェクトのコピーを作成します。ソースオブジェクトは SSE-C を使用して保存されるため、コピーリクエストで暗号化情報を指定する必要があります。デフォルトでは、明示的にリクエストした場合に限り、Amazon S3 はオブジェクトのコピーを暗号化します。この例では、新しい SSE-C キーを使用してオブジェクトの暗号化されたコピーを保存するように Amazon S3 に指示します。

注記

この例では、1 つのオペレーションでオブジェクトをアップロードする方法を示します。マルチパートアップロード API を使用して大きなオブジェクトをアップロードする場合は、この例に示したのと同じ方法で暗号化情報を指定します。AWS SDK for Java を使用するマルチパートアップロードの例については、「AWS Java SDK を使用したマルチパートアップロード (高レベル API)」と「AWS Java SDK を使用したマルチパートアップロード (低レベル API)」を参照してください。

必要な暗号化情報を追加するには、リクエストに SSECustomerKey を含めます。SSECustomerKey クラスの詳細については、「REST API を使用したお客様が用意した暗号化キーによるサーバー側の暗号化の指定」を参照してください。

SSE-C の詳細については、「お客様が用意した暗号化キーによるサーバー側の暗号化 (SSE-C) を使用したデータの保護」を参照してください。作業サンプルを作成およびテストする方法については、「Amazon S3 Java コード例のテスト」を参照してください。

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import javax.crypto.KeyGenerator; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class ServerSideEncryptionUsingClientSideEncryptionKey { private static SSECustomerKey SSE_KEY; private static AmazonS3 S3_CLIENT; private static KeyGenerator KEY_GENERATOR; public static void main(String[] args) throws IOException, NoSuchAlgorithmException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String keyName = "*** Key name ***"; String uploadFileName = "*** File path ***"; String targetKeyName = "*** Target key name ***"; // Create an encryption key. KEY_GENERATOR = KeyGenerator.getInstance("AES"); KEY_GENERATOR.init(256, new SecureRandom()); SSE_KEY = new SSECustomerKey(KEY_GENERATOR.generateKey()); try { S3_CLIENT = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Upload an object. uploadObject(bucketName, keyName, new File(uploadFileName)); // Download the object. downloadObject(bucketName, keyName); // Verify that the object is properly encrypted by attempting to retrieve it // using the encryption key. retrieveObjectMetadata(bucketName, keyName); // Copy the object into a new object that also uses SSE-C. copyObject(bucketName, keyName, targetKeyName); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } private static void uploadObject(String bucketName, String keyName, File file) { PutObjectRequest putRequest = new PutObjectRequest(bucketName, keyName, file).withSSECustomerKey(SSE_KEY); S3_CLIENT.putObject(putRequest); System.out.println("Object uploaded"); } private static void downloadObject(String bucketName, String keyName) throws IOException { GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName).withSSECustomerKey(SSE_KEY); S3Object object = S3_CLIENT.getObject(getObjectRequest); System.out.println("Object content: "); displayTextInputStream(object.getObjectContent()); } private static void retrieveObjectMetadata(String bucketName, String keyName) { GetObjectMetadataRequest getMetadataRequest = new GetObjectMetadataRequest(bucketName, keyName) .withSSECustomerKey(SSE_KEY); ObjectMetadata objectMetadata = S3_CLIENT.getObjectMetadata(getMetadataRequest); System.out.println("Metadata retrieved. Object size: " + objectMetadata.getContentLength()); } private static void copyObject(String bucketName, String keyName, String targetKeyName) throws NoSuchAlgorithmException { // Create a new encryption key for target so that the target is saved using SSE-C. SSECustomerKey newSSEKey = new SSECustomerKey(KEY_GENERATOR.generateKey()); CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName) .withSourceSSECustomerKey(SSE_KEY) .withDestinationSSECustomerKey(newSSEKey); S3_CLIENT.copyObject(copyRequest); System.out.println("Object copied"); } private static void displayTextInputStream(S3ObjectInputStream input) throws IOException { // Read one line at a time from the input stream and display each line. BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } System.out.println(); } }

AWS SDK for Java を使用した SSE-C でのその他の Amazon S3 オペレーション

前のセクションの例では、PUT、GET、Head、および COPY オペレーションで、お客様が用意したキーによるサーバー側の暗号化 (SSE-C) をリクエストする方法を示しています。このセクションでは、SSE-C をサポートするその他の API について説明します。

大きなオブジェクトをアップロードするために、マルチパートアップロード API を使用できます (「マルチパートアップロード API を使用したオブジェクトのアップロード」を参照)。高レベル API または低レベル API を使用して、大きなオブジェクトをアップロードできます。これらの API は、リクエストでの暗号化関連のヘッダーをサポートします。

次の例では、TransferManager を使用してオブジェクトを作成し、SSE-C 関連の情報を提供する方法を示します。この例では、次のような処理を実行します。

  • TransferManager.upload() メソッドを使用してオブジェクトを作成します。PutObjectRequest インスタンスで、リクエストする暗号キーの情報を指定します。Amazon S3 は、お客様が用意した暗号化キーを使用してオブジェクトを暗号化します。

  • TransferManager.copy() メソッドを呼び出してオブジェクトのコピーを作成します。この例では、新しい SSECustomerKey を使用してオブジェクトのコピーを暗号化するように Amazon S3 に指示します。ソースオブジェクトは SSE-C で暗号化されているため、CopyObjectRequest はソースオブジェクトの暗号化キーを提供し、Amazon S3 で復号してからコピーできるようにします。

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.CopyObjectRequest; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.SSECustomerKey; import com.amazonaws.services.s3.transfer.Copy; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import javax.crypto.KeyGenerator; import java.io.File; import java.security.SecureRandom; public class ServerSideEncryptionCopyObjectUsingHLwithSSEC { public static void main(String[] args) throws Exception { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String fileToUpload = "*** File path ***"; String keyName = "*** New object key name ***"; String targetKeyName = "*** Key name for object copy ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); TransferManager tm = TransferManagerBuilder.standard() .withS3Client(s3Client) .build(); // Create an object from a file. PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, new File(fileToUpload)); // Create an encryption key. KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256, new SecureRandom()); SSECustomerKey sseCustomerEncryptionKey = new SSECustomerKey(keyGenerator.generateKey()); // Upload the object. TransferManager uploads asynchronously, so this call returns immediately. putObjectRequest.setSSECustomerKey(sseCustomerEncryptionKey); Upload upload = tm.upload(putObjectRequest); // Optionally, wait for the upload to finish before continuing. upload.waitForCompletion(); System.out.println("Object created."); // Copy the object and store the copy using SSE-C with a new key. CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName); SSECustomerKey sseTargetObjectEncryptionKey = new SSECustomerKey(keyGenerator.generateKey()); copyObjectRequest.setSourceSSECustomerKey(sseCustomerEncryptionKey); copyObjectRequest.setDestinationSSECustomerKey(sseTargetObjectEncryptionKey); // Copy the object. TransferManager copies asynchronously, so this call returns immediately. Copy copy = tm.copy(copyObjectRequest); // Optionally, wait for the upload to finish before continuing. copy.waitForCompletion(); System.out.println("Copy complete."); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }