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 の使用方法を示しています。 x of AWS Encryption SDK for Java を使用して文字列を暗号化および復号化します。文字列を使用する前にバイト配列に変換します。

この例ではキーリングを使用しています。AWS KMSAWS KMSキーリングを使用して暗号化する場合、キー ID、キー ARN、エイリアス名、またはエイリアス ARN を使用して KMS キーを識別できます。復号化するときは、キー ARN を使用して KMS キーを識別する必要があります。

encryptData() メソッドを呼び出すと、暗号化テキスト、暗号化されたデータキー、暗号化コンテキストを含む暗号化されたメッセージ (CryptoResult) が返されます。CryptoResult オブジェクトで getResult を呼び出すと、暗号化されたメッセージの Base-64 でエンコードされた文字列バージョンが返され、decryptData() メソッドに渡すことができるようになります。

同様に、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()); } }