메뉴
Amazon Simple Storage Service
개발자 안내서 (API Version 2006-03-01)

AWS Java SDK를 사용하여 고객 제공 암호화 키로 서버 측 암호화 지정

다음 Java 코드 예제에서는 고객 제공 키를 사용한 서버 측 암호화(SSE-C)를 보여 줍니다(고객 제공 암호화 키(SSE-C)로 서버 측 암호화를 사용하여 데이터 보호 참조). 이 예제에서는 다음 작업을 수행합니다. 각 작업에서는 SSE-C 관련 헤더를 요청에 지정하는 방법을 보여 줍니다.

  • 객체 넣기 - 고객 제공 암호화 키를 사용하여 서버 측 암호화를 요청하는 객체를 업로드합니다.

  • 객체 가져오기 - 이전 단계에서 업로드한 객체를 다운로드합니다. 이 예제에서는 Amazon S3에서 객체를 반환하기 전에 암호를 해독할 수 있도록 사용자가 객체 업로드 당시 제공한 것과 같은 암호화 정보를 Get 요청에서 제공해야 함을 보여 줍니다.

  • 객체 메타데이터 가져오기 - 사용자가 객체 생성 시 지정한 것과 같은 암호화 정보가 있어야 객체의 메타데이터를 검색할 수 있음이 요청에 표시됩니다.

  • 객체 복사 - 이 예제는 이전에 업로드한 객체의 사본을 만듭니다. 원본 객체가 SSE-C를 사용하여 저장되기 때문에 복사 요청에 암호화 정보를 제공해야 합니다. 기본적으로 객체 복사본은 암호화되지 않습니다. 그러나 이 예제에서는 Amazon S3에서 SSE-C를 사용하여 암호화된 객체 복사본을 저장하도록 요청하므로 대상에 대한 SSE-C 암호화 정보도 제공해야 합니다.

참고

이 예제에서는 단일 작업으로 객체를 업로드하는 방법을 보여 줍니다. 멀티파트 업로드 API를 사용하여 대형 객체를 업로드할 때는 다음 예제에 나와 있는 것과 같이 요청에 제공하는 것과 같은 암호화 정보를 제공합니다. 멀티파트 업로드 AWS SDK for Java 예제는 멀티파트 업로드용 AWS Java SDK(상위 수준 API) 사용멀티파트 업로드용 AWS Java SDK(하위 수준 API) 사용을 참조하십시오.

Java용 AWS SDK는 사용자가 요청된 암호화 정보를 요청에서 추가하는 데 사용할 수 있는 SSECustomerKey 클래스를 제공합니다(SSE-C 사용 참조). 사용자는 암호화 키만 제공하면 됩니다. 그러면 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를 사용하여 대형 객체를 업로드할 수 있습니다(멀티파트 업로드 API를 사용한 객체 업로드 참조). 상위 수준 또는 하위 수준의 API를 사용하여 대형 객체를 업로드할 수 있습니다. 이들 API는 요청의 암호화 관련 헤더를 지원합니다.

  • 고급 Transfer-Utility API를 사용할 때는 암호화 관련 헤더를 TransferManager에서 제공합니다(멀티파트 업로드용 AWS Java SDK(상위 수준 API) 사용 참조).

  • 하위 수준의 API를 사용할 경우 멀티파트 업로드 요청을 시작할 때 암호화 관련 정보를 제공하고, 이후 부분 업로드 요청 시에도 동일한 암호화 정보를 제공합니다. 멀티파트 업로드 완료 요청에서는 암호화 관련 헤더를 제공할 필요가 없습니다. 예제는 멀티파트 업로드용 AWS Java SDK(하위 수준 API) 사용을 참조하십시오.

    다음 예제에서는 TransferManager를 사용하여 객체를 만들고 SSE-C 관련 정보를 제공하는 방법을 보여 줍니다. 이 예제에서는 다음 작업을 수행합니다.

    • TransferManager.upload 메서드를 사용하여 객체 생성. PutObjectRequest 인스턴스에서는 Amazon S3에서 고객 제공 암호화 키를 사용하여 암호화된 객체를 저장하도록 암호화 키 정보를 제공합니다.

    • TransferManager.copy 메서드를 호출하여 객체의 복사본 생성. CopyObjectRequest에서는 이 예제가 Amazon S3에서 역시 고객 제공 암호화 키를 사용하여 암호화된 객체 복사본을 저장하도록 요청합니다. 원본 객체가 SSE-C를 사용하여 암호화되기 때문에 Amazon S3에서 복사할 수 있기 전에 객체의 암호를 해독할 수 있도록 CopyObjectRequest 실행 시 원본 객체의 암호화 키도 제공됩니다.

    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; } } }

이 페이지에서: