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

예제 1: 클라이언트측 대칭 마스터 키를 사용하여 파일 암호화 및 업로드

이 단원에서는 다음 작업을 위해 Java용 AWS SDK를 사용하는 예제 코드를 제공합니다.

  • 먼저 256비트 AES 대칭 마스터 키를 만들어 파일에 저장

  • 먼저 클라이언트측에서 샘플 데이터를 암호화하는 S3 암호화 클라이언트를 사용하여 Amazon S3에 객체 업로드. 이 예제에서는 객체를 다운로드하고 데이터가 같은지도 확인합니다.

예제 1a: 대칭 마스터 키 만들기

Amazon S3로의 암호화된 업로드를 위해 먼저 256비트 AES 대칭 마스터 키를 생성하려면 이 코드를 실행하십시오. 예제에서는 마스터 키를 temp 디렉터리(Windows에서는 c:\Users\<username>\AppData\Local\Tmp 폴더)의 파일(secret.key)에 저장합니다.

실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은 AWS SDK for Java 사용을 참조하십시오.

Copy
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.junit.Assert; public class GenerateSymmetricMasterKey { private static final String keyDir = System.getProperty("java.io.tmpdir"); private static final String keyName = "secret.key"; public static void main(String[] args) throws Exception { //Generate symmetric 256 bit AES key. KeyGenerator symKeyGenerator = KeyGenerator.getInstance("AES"); symKeyGenerator.init(256); SecretKey symKey = symKeyGenerator.generateKey(); //Save key. saveSymmetricKey(keyDir, symKey); //Load key. SecretKey symKeyLoaded = loadSymmetricAESKey(keyDir, "AES"); Assert.assertTrue(Arrays.equals(symKey.getEncoded(), symKeyLoaded.getEncoded())); } public static void saveSymmetricKey(String path, SecretKey secretKey) throws IOException { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec( secretKey.getEncoded()); FileOutputStream keyfos = new FileOutputStream(path + "/" + keyName); keyfos.write(x509EncodedKeySpec.getEncoded()); keyfos.close(); } public static SecretKey loadSymmetricAESKey(String path, String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException{ //Read private key from file. File keyFile = new File(path + "/" + keyName); FileInputStream keyfis = new FileInputStream(keyFile); byte[] encodedPrivateKey = new byte[(int)keyFile.length()]; keyfis.read(encodedPrivateKey); keyfis.close(); //Generate secret key. return new SecretKeySpec(encodedPrivateKey, "AES"); } }

이 코드 예제는 데모용일 뿐입니다. 프로덕션용으로 사용할 경우 클라이언트측 마스터 키를 가져오거나 생성하는 방법을 보안 엔지니어에게 문의해야 합니다.

예제 1b: 대칭 키를 사용하여 Amazon S3로 파일 업로드

이전 코드 예제로 만든 대칭 마스터 키를 사용하여 샘플 데이터를 암호화하려면 이 코드를 실행하십시오. 이 예제에서는 S3 암호화 클라이언트를 사용하여 클라이언트측에서 데이터를 암호화한 다음 Amazon S3로 업로드합니다.

실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은 AWS SDK for Java 사용을 참조하십시오.

Copy
import java.io.ByteArrayInputStream; import java.util.Arrays; import java.util.Iterator; import java.util.UUID; import javax.crypto.SecretKey; import org.apache.commons.io.IOUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.junit.Assert; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3EncryptionClient; import com.amazonaws.services.s3.model.EncryptionMaterials; import com.amazonaws.services.s3.model.ListVersionsRequest; import com.amazonaws.services.s3.model.ObjectListing; 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.S3ObjectSummary; import com.amazonaws.services.s3.model.S3VersionSummary; import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider; import com.amazonaws.services.s3.model.VersionListing; public class S3ClientSideEncryptionWithSymmetricMasterKey { private static final String masterKeyDir = System.getProperty("java.io.tmpdir"); private static final String bucketName = UUID.randomUUID() + "-" + DateTimeFormat.forPattern("yyMMdd-hhmmss").print(new DateTime()); private static final String objectKey = UUID.randomUUID().toString(); public static void main(String[] args) throws Exception { SecretKey mySymmetricKey = GenerateSymmetricMasterKey .loadSymmetricAESKey(masterKeyDir, "AES"); EncryptionMaterials encryptionMaterials = new EncryptionMaterials( mySymmetricKey); AmazonS3EncryptionClient encryptionClient = new AmazonS3EncryptionClient( new ProfileCredentialsProvider(), new StaticEncryptionMaterialsProvider(encryptionMaterials)); // Create the bucket encryptionClient.createBucket(bucketName); // Upload object using the encryption client. byte[] plaintext = "Hello World, S3 Client-side Encryption Using Asymmetric Master Key!" .getBytes(); System.out.println("plaintext's length: " + plaintext.length); encryptionClient.putObject(new PutObjectRequest(bucketName, objectKey, new ByteArrayInputStream(plaintext), new ObjectMetadata())); // Download the object. S3Object downloadedObject = encryptionClient.getObject(bucketName, objectKey); byte[] decrypted = IOUtils.toByteArray(downloadedObject .getObjectContent()); // Verify same data. Assert.assertTrue(Arrays.equals(plaintext, decrypted)); deleteBucketAndAllContents(encryptionClient); } private static void deleteBucketAndAllContents(AmazonS3 client) { System.out.println("Deleting S3 bucket: " + bucketName); ObjectListing objectListing = client.listObjects(bucketName); while (true) { for ( Iterator<?> iterator = objectListing.getObjectSummaries().iterator(); iterator.hasNext(); ) { S3ObjectSummary objectSummary = (S3ObjectSummary) iterator.next(); client.deleteObject(bucketName, objectSummary.getKey()); } if (objectListing.isTruncated()) { objectListing = client.listNextBatchOfObjects(objectListing); } else { break; } }; VersionListing list = client.listVersions(new ListVersionsRequest().withBucketName(bucketName)); for ( Iterator<?> iterator = list.getVersionSummaries().iterator(); iterator.hasNext(); ) { S3VersionSummary s = (S3VersionSummary)iterator.next(); client.deleteVersion(bucketName, s.getKey(), s.getVersionId()); } client.deleteBucket(bucketName); } }