

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS Encryption SDK for Java
<a name="java"></a>

このトピックでは、 AWS Encryption SDK for Javaをインストールして使用する方法について説明します。を使用したプログラミングの詳細については AWS Encryption SDK for Java、GitHub の [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) リポジトリを参照してください。API のドキュメントについては、 AWS Encryption SDK for Javaの [Javadoc](https://aws.github.io/aws-encryption-sdk-java/) を参照してください。

**Topics**
+ [前提条件](#java-prerequisites)
+ [インストール](#java-installation)
+ [例](java-example-code.md)

## 前提条件
<a name="java-prerequisites"></a>

をインストールする前に AWS Encryption SDK for Java、次の前提条件があることを確認してください。

**Java 開発環境**  
Java 8 以降が必要になります。Oracle のウェブサイトで [Java SE のダウンロード](https://www.oracle.com/java/technologies/downloads/)に移動し、Java SE Development Kit (JDK) をダウンロードして、インストールします。  
Oracle JDK を使用する場合は、[Java Cryptography Extension (JCE) 無制限強度の管轄ポリシーファイル](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)をダウンロードして、インストールする必要があります。

**Bouncy Castle**  
には [Bouncy Castle](https://www.bouncycastle.org/download/bouncy-castle-java/) AWS Encryption SDK for Java が必要です。  
+ AWS Encryption SDK for Java バージョン 1.6.1 以降では、Bouncy Castle を使用して暗号化オブジェクトをシリアル化および逆シリアル化します。この要件を満たすには、Bouncy Castle または [Bouncy Castle FIPS](https://www.bouncycastle.org/about/bouncy-castle-fips-faq/) を使用できます。Bouncy Castle FIPS のインストールおよび設定については、[Bouncy Castle FIPS のドキュメント](https://www.bouncycastle.org/documentation/)の特に**ユーザーガイド**と**セキュリティポリシー**の PDF を参照してください。
+ 以前のバージョンの では、Bouncy Castle の cryptography API for Java AWS Encryption SDK for Java を使用しています。この要件は、FIPS 非対応の Bouncy Castle によってのみ満たされます。
Bouncy Castle がない場合は、[Java 用 Bouncy Castle のダウンロード](https://bouncycastle.org/download/bouncy-castle-java/)に移動して、JDK に対応するプロバイダーファイルをダウンロードします。また、[Apache Maven](https://maven.apache.org/) を使用して、標準の Bouncy Castle プロバイダー ([bcprov-ext-jdk15on](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on)) のアーティファクトや Bouncy Castle FIPS ([bc-fips](https://mvnrepository.com/artifact/org.bouncycastle/bc-fips)) のアーティファクトを取得することもできます。

**AWS SDK for Java**  
のバージョン 3.*x* では、 AWS KMS キーリングを使用していない場合でも AWS SDK for Java 2.x、 AWS Encryption SDK for Java が必要です。  
バージョン 2.*x* 以前の AWS Encryption SDK for Java では、 は必要ありません AWS SDK for Java。ただし、マスターキープロバイダーとして [AWS Key Management Service](https://aws.amazon.com/kms/) (AWS KMS) を使用するには、 AWS SDK for Java が必要です。 AWS Encryption SDK for Java バージョン 2.4.0 以降、 AWS Encryption SDK for Java は、1.x および 2.x 用の AWS SDK for Java. AWS Encryption SDK code のバージョン AWS SDK for Java 1.x と 2.x の両方を相互運用できます。たとえば、 AWS SDK for Java 1.x をサポートする AWS Encryption SDK コードでデータを暗号化し、 をサポートするコードを使用して復号化できます AWS SDK for Java 2.x (またはその逆）。2.4.0 より AWS Encryption SDK for Java 前のバージョンの は、 AWS SDK for Java 1.x のみをサポートしています。のバージョンの更新については AWS Encryption SDK、「」を参照してください[の移行 AWS Encryption SDK](migration.md)。  
 AWS Encryption SDK for Java コードを AWS SDK for Java 1.x から に更新するときは AWS SDK for Java 2.x、 AWS SDK for Java 1.x の[`AWSKMS`インターフェイス](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/kms/package-summary.html)への参照を の[`KmsClient`インターフェイス](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/package-summary.html)への参照に置き換えます AWS SDK for Java 2.x。 AWS Encryption SDK for Java は [`KmsAsyncClient`インターフェイス](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/KmsAsyncClient.html)をサポートしていません。また、`kms` 名前空間の代わりに、`kmssdkv2` 名前空間の AWS KMS関連オブジェクトを使用するようにコードを更新してください。  
をインストールするには AWS SDK for Java、Apache Maven を使用します。  
+ 依存関係として [AWS SDK for Java全体をインポートする](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#build-the-entire-sdk-into-your-project)には、`pom.xml` ファイルでそれを宣言します。
+ モジュール AWS KMS in AWS SDK for Java 1.x にのみ依存関係を作成するには、[特定のモジュールを指定する](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-project-maven.html#modules-dependencies)手順に従い、 `artifactId`を に設定します`aws-java-sdk-kms`。
+  AWS KMS モジュール in AWS SDK for Java 2.x にのみ依存関係を作成するには、特定の[モジュールを指定する手順に従います](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#modules-dependencies)。`groupId` を `software.amazon.awssdk` に、`artifactId` を `kms` に設定します。
その他の変更点については、[「 デベロッパーガイド」の AWS SDK for Java 「1.x と 2.x の違い](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-whats-different.html)」を参照してください。 AWS SDK for Java 2.x   
 AWS Encryption SDK デベロッパーガイドの Java の例は、 を使用します AWS SDK for Java 2.x。

## インストール
<a name="java-installation"></a>

 AWS Encryption SDK for Javaの最新バージョンをインストールします。

**注記**  
2.0.0 より AWS Encryption SDK for Java 前の のすべてのバージョンは[end-of-supportフェーズ](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)にあります。  
バージョン 2.0.x 以降から AWS Encryption SDK for Java の最新バージョンにコードやデータを変更せずに安全に更新できます。ただし、バージョン 2.0.x で導入された[新しいセキュリティ機能](about-versions.md#version-2)には下位互換性がありません。1.7.x より前のバージョンから 2.0.x 以降のバージョンに更新するには、まず AWS Encryption SDKの最新の 1.x バージョンに更新する必要があります。詳細については、「[の移行 AWS Encryption SDK](migration.md)」を参照してください。

は、次の AWS Encryption SDK for Java 方法でインストールできます。

**手動**  
をインストールするには AWS Encryption SDK for Java、[aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) GitHub リポジトリのクローンを作成するか、ダウンロードします。

**Apache Maven の使用**  
 AWS Encryption SDK for Java は、次の依存関係定義を使用して [Apache Maven](https://maven.apache.org/) を通じて使用できます。  

```
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-encryption-sdk-java</artifactId>
  <version>3.0.0</version>
</dependency>
```

SDK をインストールしたら、このガイドの [Java コード例](java-example-code.md)と [GitHub の Javadoc](https://aws.github.io/aws-encryption-sdk-java/) を見て開始します。

# AWS Encryption SDK for Java 例
<a name="java-example-code"></a>

次の例は、 を使用してデータを AWS Encryption SDK for Java 暗号化および復号する方法を示しています。これらの例は、 のバージョン 3.*x* 以降を使用する方法を示しています AWS Encryption SDK for Java。のバージョン 3.*x* には AWS Encryption SDK for Java が必要です AWS SDK for Java 2.x。のバージョン 3.*x* は AWS Encryption SDK for Java 、[マスターキープロバイダー](concepts.md#master-key-provider)を[キーリングに置き換えます](concepts.md#keyring)。前バージョンを使用する例については、GitHub の [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) リポジトリの[リリース](https://github.com/aws/aws-encryption-sdk-java/releases)リストで使用中のリリースを検索してください。

**Topics**
+ [文字列](#java-example-strings)
+ [バイトストリーム](#java-example-streams)
+ [複数のマスターキープロバイダーでのバイトストリーム](#java-example-multiple-providers)

## 文字列の暗号化と復号
<a name="java-example-strings"></a>

次の例は、 のバージョン 3.*x* を使用して文字列 AWS Encryption SDK for Java を暗号化および復号する方法を示しています。文字列を使用する前にバイト配列に変換します。

この例では、 [AWS KMS キーリング](use-kms-keyring.md)を使用します。 AWS KMS キーリングで暗号化する場合、キー ID、キー ARN、エイリアス名、またはエイリアス ARN を使用して KMS キーを識別できます。復号するときは、キー ARN を使用して KMS キーを識別する必要があります。

`encryptData()` メソッドを呼び出すと、暗号化テキスト、暗号化されたデータキー、暗号化コンテキストを含む[暗号化されたメッセージ](concepts.md#message) (`CryptoResult`) が返されます。`CryptoResult` オブジェクトで `getResult` を呼び出すと、[暗号化されたメッセージ](message-format.md)の 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);
  }
}
```

## バイトストリームの暗号化と復号
<a name="java-example-streams"></a>

次の例は、 を使用してバイトストリーム AWS Encryption SDK を暗号化および復号する方法を示しています。

この例では、[Raw AES キーリング](use-raw-aes-keyring.md)を使用します。

暗号化するときには、`AwsCrypto.builder() .withEncryptionAlgorithm()` メソッドを使用して、[デジタル署名](concepts.md#digital-sigs)のないアルゴリズムスイートを指定します。復号化時に、暗号化テキストが署名なしであることを確認するために、この例では `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");
    }
}
```

## マルチキーリングを使用したバイトストリームの暗号化と復号
<a name="java-example-multiple-providers"></a>

次の例は、[マルチキーリング](use-multi-keyring.md) AWS Encryption SDK で を使用する方法を示しています。マルチキーリングを使用してデータを暗号化する場合は、そのキーリングに含まれる任意のラッピングキーを使用してそのデータを復号できます。この例では、 [AWS KMS キーリング](use-kms-keyring.md)と [Raw RSA キーリング](use-raw-rsa-keyring.md)を子キーリングとして使用します。

この例では、[デジタル署名](concepts.md#digital-sigs)を含む[デフォルトのアルゴリズムスイート](supported-algorithms.md)で暗号化します。ストリーミング時、 は整合性チェックの後、デジタル署名を検証する前にプレーンテキストを 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());

    }
}
```