メニュー
Amazon Simple Storage Service
開発者ガイド (API Version 2006-03-01)

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

次の Java コード例では、お客様が用意したキーによるサーバー側の暗号化(SSE-C)を示しています(「お客様が用意した暗号化キーによるサーバー側の暗号化(SSE-C)を使用したデータの保護」を参照)。この例では以下のオペレーションを実行します。各オペレーションは、リクエスト内で SSE-C 関連のヘッダーを指定する方法を示しています。

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

  • Get object – 前のステップでアップロードしたオブジェクトをダウンロードします。この例は、Amazon S3 がオブジェクトを復号して返すことができるように、オブジェクトをアップロードしたときに提供したものと同じ暗号化情報を Get リクエストで提供する必要があることを示しています。

  • Get object metadata – このリクエストは、オブジェクトのメタデータを取得するには、オブジェクトを作成したときに指定したものと同じ暗号化情報が必要であることを示しています。

  • Copy object – この例は、以前にアップロードしたオブジェクトのコピーを作成します。ソースオブジェクトは SSE-C を使用して保存されているため、コピーリクエストで暗号化情報を提供する必要があります。デフォルトでは、オブジェクトのコピーは暗号化されません。ただし、この例では、オブジェクトのコピーを SSE-C を使用して暗号化して保存することを Amazon S3 にリクエストしているため、ターゲットについても SSE-C 暗号化情報も指定する必要があります。

注記

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

AWS SDK for Java は、リクエストに必要な暗号化情報(「SSE-C の使用」を参照)を追加するための SSECustomerKey クラスを提供します。暗号化キーのみを指定する必要があります。Java SDK によって、暗号化キーとアルゴリズムの MD5 ダイジェストの値が設定されます。

作業サンプルを作成およびテストする方法については、「Java コード例のテスト」を参照してください。

Copy
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.CopyObjectRequest; import com.amazonaws.services.s3.model.GetObjectMetadataRequest; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectInputStream; import com.amazonaws.services.s3.model.SSECustomerKey; public class ServerSideEncryptionUsingClientSideEncryptionKey { private static String bucketName = "*** Provide bucket name ***"; private static String keyName = "*** Provide key ***"; private static String uploadFileName = "*** Provide file name ***"; private static String targetKeyName = "*** provide target key ***"; private static AmazonS3 s3client; public static void main(String[] args) throws IOException, NoSuchAlgorithmException { s3client = new AmazonS3Client(new ProfileCredentialsProvider()); try { System.out.println("Uploading a new object to S3 from a file\n"); File file = new File(uploadFileName); // Create encryption key. SecretKey secretKey = generateSecretKey(); SSECustomerKey sseKey = new SSECustomerKey(secretKey); // 1. Upload object. uploadObject(file, sseKey); // 2. Download object. downloadObject(sseKey); // 3. Get object metadata (and verify AES256 encryption). retrieveObjectMetadata(sseKey); // 4. Copy object (both source and object use SSE-C). copyObject(sseKey); } catch (AmazonServiceException ase) { System.out.println("Caught an AmazonServiceException, which " + "means your request made it " + "to Amazon S3, but was rejected with an error response" + " for some reason."); System.out.println("Error Message: " + ase.getMessage()); System.out.println("HTTP Status Code: " + ase.getStatusCode()); System.out.println("AWS Error Code: " + ase.getErrorCode()); System.out.println("Error Type: " + ase.getErrorType()); System.out.println("Request ID: " + ase.getRequestId()); } catch (AmazonClientException ace) { System.out.println("Caught an AmazonClientException, which " + "means the client encountered " + "an internal error while trying to " + "communicate with S3, " + "such as not being able to access the network."); System.out.println("Error Message: " + ace.getMessage()); } } private static void copyObject(SSECustomerKey sseKey) { // Create new encryption key for target so it is saved using sse-c SecretKey secretKey2 = generateSecretKey(); SSECustomerKey newSseKey = new SSECustomerKey(secretKey2); CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName) .withSourceSSECustomerKey(sseKey) .withDestinationSSECustomerKey(newSseKey); s3client.copyObject(copyRequest); System.out.println("Object copied"); } private static void retrieveObjectMetadata(SSECustomerKey sseKey) { GetObjectMetadataRequest getMetadataRequest = new GetObjectMetadataRequest(bucketName, keyName) .withSSECustomerKey(sseKey); ObjectMetadata objectMetadata = s3client.getObjectMetadata(getMetadataRequest); System.out.println("object size " + objectMetadata.getContentLength()); System.out.println("Metadata retrieved"); } private static PutObjectRequest uploadObject(File file, SSECustomerKey sseKey) { // 1. Upload Object. PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, file) .withSSECustomerKey(sseKey); s3client.putObject(putObjectRequest); System.out.println("Object uploaded"); return putObjectRequest; } private static void downloadObject(SSECustomerKey sseKey) throws IOException { // Get a range of bytes from an object. GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName) .withSSECustomerKey(sseKey); S3Object s3Object = s3client.getObject(getObjectRequest); System.out.println("Printing bytes retrieved."); displayTextInputStream(s3Object.getObjectContent()); } private static void displayTextInputStream(S3ObjectInputStream input) throws IOException { // Read one text line at a time and display. BufferedReader reader = new BufferedReader(new InputStreamReader(input)); while (true) { String line = reader.readLine(); if (line == null) break; System.out.println(" " + line); } System.out.println(); } private static SecretKey generateSecretKey() { try { KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(256, new SecureRandom()); return generator.generateKey(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); return null; } } }

その他の Amazon S3 オペレーションと SSE-C

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

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

  • 高レベルの転送ユーティリティ API を使用するときには、TransferManager で暗号化固有のヘッダーを提供します(「AWS Java SDK を使用したマルチパートアップロード (高レベル API)」を参照)。

  • 低レベル API を使用する場合は、マルチパートアップロードの開始リクエストで暗号化関連情報を提供し、以降のパートのアップロードリクエストでは同じ暗号化情報を提供します。マルチパートアップロードの完了リクエストでは、暗号化固有のヘッダーを提供する必要はありません。例については、「AWS Java SDK を使用したマルチパートアップロード (低レベル API)」を参照してください。

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

    • TransferManager.upload メソッドを使用してオブジェクトを作成します。お客様が用意した暗号化キーを使用して暗号化されたオブジェクトを Amazon S3 が格納することをリクエストするために、PutObjectRequest インスタンスで暗号化キーの情報を提供します。

    • TransferManager.copy メソッドを呼び出してオブジェクトのコピーを作成します。この例では、CopyObjectRequest で、オブジェクトのコピーもお客様が用意した暗号化キーを使って暗号化して保存することを Amazon S3 にリクエストしています。ソースオブジェクトが SSE-C を使って暗号化されているため、CopyObjectRequest では、Amazon S3 がコピーの前にオブジェクトを復号できるように、ソースオブジェクトの暗号化キーも提供しています。

    Copy
    import java.io.File; import java.security.SecureRandom; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import com.amazonaws.AmazonClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; 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.Upload; public class ServerSideEncryptionCopyObjectUsingHLwithSSEC { public static void main(String[] args) throws Exception { String existingBucketName = "*** Provide existing bucket name ***"; String fileToUpload = "*** file path ***"; String keyName = "*** New object key ***"; String targetKeyName = "*** Key name for object copy ***"; TransferManager tm = new TransferManager(new ProfileCredentialsProvider()); // 1. first create an object from a file. PutObjectRequest putObjectRequest = new PutObjectRequest(existingBucketName, keyName, new File(fileToUpload)); // we want object stored using SSE-C. So we create encryption key. SecretKey secretKey1 = generateSecretKey(); SSECustomerKey sseCustomerEncryptionKey1 = new SSECustomerKey(secretKey1); putObjectRequest.setSSECustomerKey(sseCustomerEncryptionKey1); // now create object. //Upload upload = tm.upload(existingBucketName, keyName, new File(sourceFile)); Upload upload = tm.upload(putObjectRequest); try { // Or you can block and wait for the upload to finish upload.waitForCompletion(); //tm.getAmazonS3Client().putObject(putObjectRequest); System.out.println("Object created."); } catch (AmazonClientException amazonClientException) { System.out.println("Unable to upload file, upload was aborted."); amazonClientException.printStackTrace(); } // 2. Now make object copy (in the same bucket). Store target using sse-c. CopyObjectRequest copyObjectRequest = new CopyObjectRequest(existingBucketName, keyName, existingBucketName, targetKeyName); SecretKey secretKey2 = generateSecretKey(); SSECustomerKey sseTargetObjectEncryptionKey = new SSECustomerKey(secretKey2); copyObjectRequest.setSourceSSECustomerKey(sseCustomerEncryptionKey1); copyObjectRequest.setDestinationSSECustomerKey(sseTargetObjectEncryptionKey); // TransferManager processes all transfers asynchronously, // so this call will return immediately. Copy copy = tm.copy(copyObjectRequest); try { // Or you can block and wait for the upload to finish copy.waitForCompletion(); System.out.println("Copy complete."); } catch (AmazonClientException amazonClientException) { System.out.println("Unable to upload file, upload was aborted."); amazonClientException.printStackTrace(); } } private static SecretKey generateSecretKey() { KeyGenerator generator; try { generator = KeyGenerator.getInstance("AES"); generator.init(256, new SecureRandom()); return generator.generateKey(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); return null; } } }