AWS Encryption SDK for Java 예제 - AWS Encryption SDK

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS Encryption SDK for Java 예제

다음 예제에서는 AWS Encryption SDK for Java를 사용하여 데이터를 암호화 및 복호화하는 방법을 보여줍니다. 이 예제는 버전 3을 사용하는 방법을 보여줍니다. x 및 이후 버전AWS Encryption SDK for Java. 버전 3. x는 마스터 키 제공자를 키링으로 AWS Encryption SDK for Java 대체합니다. 이전 버전을 사용하는 예제의 경우 aws-encryption-sdk-java리포지토리의 릴리스 목록에서 해당 릴리스를 찾아보십시오. GitHub

문자열 암호화 및 복호화

다음 예제는 버전 3을 사용하는 방법을 보여줍니다. 문자열을 암호화하고 AWS Encryption SDK for Java 해독하는 데 사용되는 x입니다. 문자열을 사용하기 전에 바이트 배열로 변환하세요.

이 예제에서는 키링을 사용합니다. AWS KMS AWS KMS키링으로 암호화하는 경우 키 ID, 키 ARN, 별칭 이름 또는 별칭 ARN을 사용하여 KMS 키를 식별할 수 있습니다. 암호를 해독할 때는 키 ARN을 사용하여 KMS 키를 식별해야 합니다.

encryptData() 메서드를 호출하면 사이퍼텍스트, 암호화된 데이터 키 및 암호화 컨텍스트를 포함하는 암호화된 메시지(CryptoResult)가 반환됩니다. CryptoResult 객체에서 getResult를 호출하면 decryptData() 메서드에 전달할 수 있는 암호화된 메시지의 base-64 인코딩 문자열 버전이 반환됩니다.

마찬가지로 decryptData()를 호출하면 반환되는 CryptoResult 객체에는 일반 텍스트 메시지와 AWS KMS key ID가 포함됩니다. 애플리케이션이 일반 텍스트를 반환하기 전에 암호화된 메시지의 AWS KMS key ID 및 암호화 컨텍스트가 예상한 것인지 확인하세요.

// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.keyrings; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CommitmentPolicy; import com.amazonaws.encryptionsdk.CryptoResult; import software.amazon.cryptography.materialproviders.IKeyring; import software.amazon.cryptography.materialproviders.MaterialProviders; import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput; import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.Map; /** * Encrypts and then decrypts data using an AWS KMS Keyring. * * <p>Arguments: * * <ol> * <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master * key (CMK), see 'Viewing Keys' at * http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html * </ol> */ public class BasicEncryptionKeyringExample { private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); public static void main(final String[] args) { final String keyArn = args[0]; encryptAndDecryptWithKeyring(keyArn); } public static void encryptAndDecryptWithKeyring(final String keyArn) { // 1. Instantiate the SDK // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy, // which means this client only encrypts using committing algorithm suites and enforces // that the client will only decrypt encrypted messages that were created with a committing // algorithm suite. // This is the default commitment policy if you build the client with // `AwsCrypto.builder().build()` // or `AwsCrypto.standard()`. final AwsCrypto crypto = AwsCrypto.builder() .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt) .build(); // 2. Create the AWS KMS keyring. // This example creates a multi keyring, which automatically creates the KMS client. final MaterialProviders materialProviders = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMultiKeyringInput keyringInput = CreateAwsKmsMultiKeyringInput.builder().generator(keyArn).build(); final IKeyring kmsKeyring = materialProviders.CreateAwsKmsMultiKeyring(keyringInput); // 3. Create an encryption context // We recommend using an encryption context whenever possible // to protect integrity. This sample uses placeholder values. // For more information see: // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management final Map<String, String> encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); // 4. Encrypt the data final CryptoResult<byte[], ?> encryptResult = crypto.encryptData(kmsKeyring, EXAMPLE_DATA, encryptionContext); final byte[] ciphertext = encryptResult.getResult(); // 5. Decrypt the data final CryptoResult<byte[], ?> decryptResult = crypto.decryptData( kmsKeyring, ciphertext, // Verify that the encryption context in the result contains the // encryption context supplied to the encryptData method encryptionContext); // 6. Verify that the decrypted plaintext matches the original plaintext assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); } }

바이트 스트림 암호화 및 복호화

다음 예제에서는 AWS Encryption SDK를 사용하여 바이트 스트림을 암호화 및 복호화하는 방법을 보여줍니다.

이 예에서는 Raw AES 키링을 사용합니다.

암호화할 때 이 예제에서는 AwsCrypto.builder() .withEncryptionAlgorithm() 메서드를 사용하여 디지털 서명이 없는 알고리즘 제품군을 지정합니다. 이 예제에서는 복호화할 때 사이퍼텍스트에 서명이 없는지 확인하기 위해 createUnsignedMessageDecryptingStream() 메서드를 사용합니다. 이 createUnsignedMessageDecryptingStream() 메서드는 디지털 서명이 있는 암호문을 발견하면 실패합니다.

디지털 서명이 포함된 기본 알고리즘 제품군으로 암호화하는 경우 다음 예제와 같이 createDecryptingStream() 메서드를 대신 사용하세요.

// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.keyrings; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CommitmentPolicy; import com.amazonaws.encryptionsdk.CryptoAlgorithm; import com.amazonaws.encryptionsdk.CryptoInputStream; import com.amazonaws.encryptionsdk.jce.JceMasterKey; import com.amazonaws.util.IOUtils; import software.amazon.cryptography.materialproviders.IKeyring; import software.amazon.cryptography.materialproviders.MaterialProviders; import software.amazon.cryptography.materialproviders.model.AesWrappingAlg; import software.amazon.cryptography.materialproviders.model.CreateRawAesKeyringInput; import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.security.SecureRandom; import java.util.Collections; import java.util.Map; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * <p> * Encrypts and then decrypts a file under a random key. * * <p> * Arguments: * <ol> * <li>Name of file containing plaintext data to encrypt * </ol> * * <p> * This program demonstrates using a standard Java {@link SecretKey} object as a {@link IKeyring} to * encrypt and decrypt streaming data. */ public class FileStreamingKeyringExample { private static String srcFile; public static void main(String[] args) throws IOException { srcFile = args[0]; // In this example, we generate a random key. In practice, // you would get a key from an existing store SecretKey cryptoKey = retrieveEncryptionKey(); // Create a Raw Aes Keyring using the random key and an AES-GCM encryption algorithm final MaterialProviders materialProviders = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateRawAesKeyringInput keyringInput = CreateRawAesKeyringInput.builder() .wrappingKey(ByteBuffer.wrap(cryptoKey.getEncoded())) .keyNamespace("Example") .keyName("RandomKey") .wrappingAlg(AesWrappingAlg.ALG_AES128_GCM_IV12_TAG16) .build(); IKeyring keyring = materialProviders.CreateRawAesKeyring(keyringInput); // Instantiate the SDK. // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy, // which means this client only encrypts using committing algorithm suites and enforces // that the client will only decrypt encrypted messages that were created with a committing // algorithm suite. // This is the default commitment policy if you build the client with // `AwsCrypto.builder().build()` // or `AwsCrypto.standard()`. // This example encrypts with an algorithm suite that doesn't include signing for faster decryption, // since this use case assumes that the contexts that encrypt and decrypt are equally trusted. final AwsCrypto crypto = AwsCrypto.builder() .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt) .withEncryptionAlgorithm(CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY) .build(); // Create an encryption context to identify the ciphertext Map<String, String> context = Collections.singletonMap("Example", "FileStreaming"); // Because the file might be too large to load into memory, we stream the data, instead of //loading it all at once. FileInputStream in = new FileInputStream(srcFile); CryptoInputStream<JceMasterKey> encryptingStream = crypto.createEncryptingStream(keyring, in, context); FileOutputStream out = new FileOutputStream(srcFile + ".encrypted"); IOUtils.copy(encryptingStream, out); encryptingStream.close(); out.close(); // Decrypt the file. Verify the encryption context before returning the plaintext. // Since the data was encrypted using an unsigned algorithm suite, use the recommended // createUnsignedMessageDecryptingStream method, which only accepts unsigned messages. in = new FileInputStream(srcFile + ".encrypted"); CryptoInputStream<JceMasterKey> decryptingStream = crypto.createUnsignedMessageDecryptingStream(keyring, in); // Does it contain the expected encryption context? if (!"FileStreaming".equals(decryptingStream.getCryptoResult().getEncryptionContext().get("Example"))) { throw new IllegalStateException("Bad encryption context"); } // Write the plaintext data to disk. out = new FileOutputStream(srcFile + ".decrypted"); IOUtils.copy(decryptingStream, out); decryptingStream.close(); out.close(); } /** * In practice, this key would be saved in a secure location. * For this demo, we generate a new random key for each operation. */ private static SecretKey retrieveEncryptionKey() { SecureRandom rnd = new SecureRandom(); byte[] rawKey = new byte[16]; // 128 bits rnd.nextBytes(rawKey); return new SecretKeySpec(rawKey, "AES"); } }

멀티 키링으로 바이트 스트림 암호화 및 복호화

다음 예제는 를 멀티 키링과 함께 사용하는 방법을 보여줍니다. AWS Encryption SDK 다중 키링을 사용하여 데이터를 암호화하는 경우 해당 키링의 모든 래핑 키로 해당 데이터를 복호화할 수 있습니다. 이 예제에서는 AWS KMS키링과 Raw RSA 키링을 하위 키링으로 사용합니다.

이 예제는 디지털 서명이 포함된 기본 알고리즘 제품군을 사용하여 암호화합니다. 스트리밍할 때 AWS Encryption SDK는 무결성 검사를 거친 후 디지털 서명을 확인하기 전에 일반 텍스트를 릴리스합니다. 서명이 확인될 때까지 일반 텍스트를 사용하지 않도록 이 예제에서는 일반 텍스트를 버퍼링하고 복호화 및 확인이 완료될 때만 디스크에 씁니다.

// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.keyrings; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CommitmentPolicy; import com.amazonaws.encryptionsdk.CryptoOutputStream; import com.amazonaws.util.IOUtils; import software.amazon.cryptography.materialproviders.IKeyring; import software.amazon.cryptography.materialproviders.MaterialProviders; import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput; import software.amazon.cryptography.materialproviders.model.CreateMultiKeyringInput; import software.amazon.cryptography.materialproviders.model.CreateRawRsaKeyringInput; import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig; import software.amazon.cryptography.materialproviders.model.PaddingScheme; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.util.Collections; /** * <p> * Encrypts a file using both AWS KMS Key and an asymmetric key pair. * * <p> * Arguments: * <ol> * <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS key, * see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html * * <li>Name of file containing plaintext data to encrypt * </ol> * <p> * You might use AWS Key Management Service (AWS KMS) for most encryption and decryption operations, but * still want the option of decrypting your data offline independently of AWS KMS. This sample * demonstrates one way to do this. * <p> * The sample encrypts data under both an AWS KMS key and an "escrowed" RSA key pair * so that either key alone can decrypt it. You might commonly use the AWS KMS key for decryption. However, * at any time, you can use the private RSA key to decrypt the ciphertext independent of AWS KMS. * <p> * This sample uses the RawRsaKeyring to generate a RSA public-private key pair * and saves the key pair in memory. In practice, you would store the private key in a secure offline * location, such as an offline HSM, and distribute the public key to your development team. */ public class EscrowedEncryptKeyringExample { private static ByteBuffer publicEscrowKey; private static ByteBuffer privateEscrowKey; public static void main(final String[] args) throws Exception { // This sample generates a new random key for each operation. // In practice, you would distribute the public key and save the private key in secure // storage. generateEscrowKeyPair(); final String kmsArn = args[0]; final String fileName = args[1]; standardEncrypt(kmsArn, fileName); standardDecrypt(kmsArn, fileName); escrowDecrypt(fileName); } private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception { // Encrypt with the KMS key and the escrowed public key // 1. Instantiate the SDK // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy, // which means this client only encrypts using committing algorithm suites and enforces // that the client will only decrypt encrypted messages that were created with a committing // algorithm suite. // This is the default commitment policy if you build the client with // `AwsCrypto.builder().build()` // or `AwsCrypto.standard()`. final AwsCrypto crypto = AwsCrypto.builder() .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt) .build(); // 2. Create the AWS KMS keyring. // This example creates a multi keyring, which automatically creates the KMS client. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMultiKeyringInput keyringInput = CreateAwsKmsMultiKeyringInput.builder() .generator(kmsArn) .build(); IKeyring kmsKeyring = matProv.CreateAwsKmsMultiKeyring(keyringInput); // 3. Create the Raw Rsa Keyring with Public Key. final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder() .keyName("Escrow") .keyNamespace("Escrow") .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1) .publicKey(publicEscrowKey) .build(); IKeyring rsaPublicKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput); // 4. Create the multi-keyring. final CreateMultiKeyringInput createMultiKeyringInput = CreateMultiKeyringInput.builder() .generator(kmsKeyring) .childKeyrings(Collections.singletonList(rsaPublicKeyring)) .build(); IKeyring multiKeyring = matProv.CreateMultiKeyring(createMultiKeyringInput); // 5. Encrypt the file // To simplify this code example, we omit the encryption context. Production code should always // use an encryption context. final FileInputStream in = new FileInputStream(fileName); final FileOutputStream out = new FileOutputStream(fileName + ".encrypted"); final CryptoOutputStream<?> encryptingStream = crypto.createEncryptingStream(multiKeyring, out); IOUtils.copy(in, encryptingStream); in.close(); encryptingStream.close(); } private static void standardDecrypt(final String kmsArn, final String fileName) throws Exception { // Decrypt with the AWS KMS key and the escrow public key. // 1. Instantiate the SDK. // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy, // which means this client only encrypts using committing algorithm suites and enforces // that the client will only decrypt encrypted messages that were created with a committing // algorithm suite. // This is the default commitment policy if you build the client with // `AwsCrypto.builder().build()` // or `AwsCrypto.standard()`. final AwsCrypto crypto = AwsCrypto.builder() .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt) .build(); // 2. Create the AWS KMS keyring. // This example creates a multi keyring, which automatically creates the KMS client. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMultiKeyringInput keyringInput = CreateAwsKmsMultiKeyringInput.builder() .generator(kmsArn) .build(); IKeyring kmsKeyring = matProv.CreateAwsKmsMultiKeyring(keyringInput); // 3. Create the Raw Rsa Keyring with Public Key. final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder() .keyName("Escrow") .keyNamespace("Escrow") .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1) .publicKey(publicEscrowKey) .build(); IKeyring rsaPublicKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput); // 4. Create the multi-keyring. final CreateMultiKeyringInput createMultiKeyringInput = CreateMultiKeyringInput.builder() .generator(kmsKeyring) .childKeyrings(Collections.singletonList(rsaPublicKeyring)) .build(); IKeyring multiKeyring = matProv.CreateMultiKeyring(createMultiKeyringInput); // 5. Decrypt the file // To simplify this code example, we omit the encryption context. Production code should always // use an encryption context. final FileInputStream in = new FileInputStream(fileName + ".encrypted"); final FileOutputStream out = new FileOutputStream(fileName + ".decrypted"); // Since we are using a signing algorithm suite, we avoid streaming decryption directly to the output file, // to ensure that the trailing signature is verified before writing any untrusted plaintext to disk. final ByteArrayOutputStream plaintextBuffer = new ByteArrayOutputStream(); final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(multiKeyring, plaintextBuffer); IOUtils.copy(in, decryptingStream); in.close(); decryptingStream.close(); final ByteArrayInputStream plaintextReader = new ByteArrayInputStream(plaintextBuffer.toByteArray()); IOUtils.copy(plaintextReader, out); out.close(); } private static void escrowDecrypt(final String fileName) throws Exception { // You can decrypt the stream using only the private key. // This method does not call AWS KMS. // 1. Instantiate the SDK final AwsCrypto crypto = AwsCrypto.standard(); // 2. Create the Raw Rsa Keyring with Private Key. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder() .keyName("Escrow") .keyNamespace("Escrow") .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1) .publicKey(publicEscrowKey) .privateKey(privateEscrowKey) .build(); IKeyring escrowPrivateKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput); // 3. Decrypt the file // To simplify this code example, we omit the encryption context. Production code should always // use an encryption context. final FileInputStream in = new FileInputStream(fileName + ".encrypted"); final FileOutputStream out = new FileOutputStream(fileName + ".deescrowed"); final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(escrowPrivateKeyring, out); IOUtils.copy(in, decryptingStream); in.close(); decryptingStream.close(); } private static void generateEscrowKeyPair() throws GeneralSecurityException { final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); kg.initialize(4096); // Escrow keys should be very strong final KeyPair keyPair = kg.generateKeyPair(); publicEscrowKey = RawRsaKeyringExample.getPEMPublicKey(keyPair.getPublic()); privateEscrowKey = RawRsaKeyringExample.getPEMPrivateKey(keyPair.getPrivate()); } }