翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
AWS KMS 階層キーリング
AWS KMS 階層キーリングを使用すると、データを暗号化または復号する AWS KMS たびに を呼び出すことなく、対称暗号化 KMS キーで暗号化マテリアルを保護できます。これは、 への呼び出しを最小限に抑える必要があるアプリケーションや AWS KMS、セキュリティ要件に違反することなく一部の暗号化マテリアルを再利用できるアプリケーションに適しています。
階層キーリングは、Amazon DynamoDB テーブルに保持されている AWS KMS 保護されたブランチキーを使用し、暗号化および復号オペレーションで使用されるブランチキーマテリアルをローカルにキャッシュすることで、 AWS KMS 呼び出しの数を減らす暗号化マテリアルキャッシュソリューションです。DynamoDB テーブルは、ブランチキーを管理および保護するキーストアとして機能します。アクティブなブランチキーと、ブランチキーの以前のすべてのバージョンが格納されます。アクティブなブランチキーは、ブランチキーの最新バージョンです。階層キーリングは、一意のデータキーを使用して各メッセージを暗号化し、暗号化リクエストごとに各データ暗号化キーを暗号化し、アクティブなブランチキーから派生した一意のラッピングキーを使用して各データ暗号化キーを暗号化します。階層キーリングは、アクティブなブランチキーと、その導出ラッピングキーの間に確立された階層に依拠します。
階層キーリングは通常、複数のリクエストを満たすために各ブランチキーバージョンを使用します。ただし、ユーザーがアクティブなブランチキーを再利用する範囲を制御し、アクティブなブランチキーをローテーションする頻度を決定します。ブランチキーのアクティブなバージョンは、ローテーションされるまでアクティブなままとなります。アクティブなブランチキーの以前のバージョンは暗号化オペレーションの実行には使用されませんが、引き続きクエリを実行して復号オペレーションに使用できます。
階層キーリングをインスタンス化すると、ローカルキャッシュが作成されます。ブランチキーマテリアルがローカルキャッシュ内に格納される最大時間 (ブランチキーマテリアルが期限切れになってキャッシュから削除されるまでの時間) を定義するキャッシュ制限を指定します。階層キーリングは、 オペレーションで が初めて指定されたときに、ブランチキーを復号し、ブランチキーマテリアルをアセンブルするために branch-key-id 1 回の AWS KMS 呼び出しを行います。その後、ブランチキーマテリアルはローカルキャッシュに格納され、キャッシュ制限が期限切れになるまで、その branch-key-id を指定するすべての暗号化および復号オペレーションのために再利用されます。ブランチキーマテリアルをローカルキャッシュに保存すると、 AWS KMS 呼び出しが減ります。例えば、キャッシュ制限が 15 分である場合を考えてみましょう。そのキャッシュ制限内で 10,000 回の暗号化オペレーションを実行する場合、従来の AWS KMS キーリングは 10,000 回の暗号化オペレーションを満たすために 10,000 回の AWS KMS 呼び出しを行う必要があります。アクティブな が 1 つある場合branch-key-id、階層キーリングは 10,000 回の暗号化オペレーションを満たすために 1 回の AWS KMS 呼び出しを行うだけで済みます。
ローカルキャッシュは、暗号化マテリアルと復号マテリアルを分離します。暗号化マテリアルはアクティブなブランチキーからアセンブルされ、キャッシュ制限の有効期限が切れるまですべての暗号化オペレーションに再利用されます。復号マテリアルは、暗号化されたフィールドのメタデータで識別されるブランチキー ID とバージョンからアセンブルされ、キャッシュ制限の有効期限が切れるまで、ブランチキー ID とバージョンに関連するすべての復号オペレーションに再利用されます。ローカルキャッシュは、一度に同じブランチキーの複数のバージョンを保存できます。ローカルキャッシュが を使用するように設定されている場合branch key ID supplier、一度に複数のアクティブなブランチキーからのブランチキーマテリアルを保存することもできます。
の階層キーリングに関するすべての言及は、 AWS KMS 階層キーリング AWS Encryption SDK を参照します。
プログラミング言語の互換性
階層キーリングは、次のプログラミング言語とバージョンでサポートされています。
-
のバージョン 3.x AWS Encryption SDK for Java
-
AWS Encryption SDK for .NET のバージョン 4.x 以降
-
オプションの MPL 依存関係とともに AWS Encryption SDK for Python使用する場合、 のバージョン 4.x。
-
AWS Encryption SDK for Rust のバージョン 1.x
-
AWS Encryption SDK for Go のバージョン 0.1.x 以降
仕組み
次のチュートリアルでは、階層キーリングが暗号化および復号マテリアルをアセンブルする方法と、暗号化および復号オペレーションのためにキーリングが実行するさまざまな呼び出しについて説明します。ラッピングキーの導出とプレーンテキストデータキーの暗号化プロセスの技術的な詳細については、「AWS KMS 階層キーリングの技術的な詳細」を参照してください。
暗号化および署名
次のチュートリアルでは、階層キーリングが暗号化マテリアルをアセンブルし、一意のラッピングキーを導出する方法について説明します。
-
暗号化メソッドは、階層キーリングに暗号化マテリアルを要求します。キーリングはプレーンテキストデータキーを生成し、ラッピングキーを生成するために、ローカルキャッシュに有効なブランチマテリアルがあるかどうかを確認します。有効なブランチキーマテリアルがある場合、キーリングはステップ 4 に進みます。
-
有効なブランチキーマテリアルがない場合、階層キーリングはキーストアにアクティブなブランチキーをクエリします。
-
キーストアは AWS KMS を呼び出してアクティブなブランチキーを復号し、プレーンテキストのアクティブなブランチキーを返します。アクティブなブランチキーを識別するデータは、 AWS KMSに対する復号呼び出しで追加認証データ (AAD) を提供するためにシリアル化されます。
-
キーストアは、プレーンテキストのブランチキーと、ブランチキーのバージョンなど、それを識別するデータを返します。
-
階層キーリングはブランチキーマテリアル (プレーンテキストブランチキーとブランチキーバージョン) をアセンブルし、それらのコピーをローカルキャッシュに格納します。
-
階層キーリングは、プレーンテキストブランチキーと 16 バイトのランダムソルトから一意のラッピングキーを導出します。生成されたラッピングキーを使用して、プレーンテキストデータキーのコピーを暗号化します。
暗号化方法では、暗号化マテリアルを使用してデータを暗号化します。詳細については、「 がデータを AWS Encryption SDK 暗号化する方法」を参照してください。
復号と検証
次のチュートリアルでは、階層型キーリングが復号マテリアルを組み立て、暗号化されたデータキーを復号する方法について説明します。
-
復号方法では、暗号化されたメッセージから暗号化されたデータキーを識別し、階層型キーリングに渡します。
-
階層型キーリングは、ブランチキーバージョン、16 バイトのソルト、およびデータキーの暗号化方法を説明するその他の情報を含む、暗号化されたデータキーを識別するデータを逆シリアル化します。
詳細については、「AWS KMS 階層キーリングの技術的な詳細」を参照してください。
-
階層キーリングは、ステップ 2 で特定されたブランチキーのバージョンと一致する有効なブランチキーマテリアルがローカルキャッシュ内に存在するかどうかをチェックします。有効なブランチキーマテリアルがある場合、キーリングはステップ 6 に進みます。
-
有効なブランチキーマテリアルがない場合、階層キーリングは、ステップ 2 で識別されたブランチキーバージョンに一致するブランチキーについてキーストアをクエリします。
-
キーストアは AWS KMS を呼び出してブランチキーを復号し、プレーンテキストのアクティブなブランチキーを返します。アクティブなブランチキーを識別するデータは、 AWS KMSに対する復号呼び出しで追加認証データ (AAD) を提供するためにシリアル化されます。
-
キーストアは、プレーンテキストのブランチキーと、ブランチキーのバージョンなど、それを識別するデータを返します。
-
階層キーリングはブランチキーマテリアル (プレーンテキストブランチキーとブランチキーバージョン) をアセンブルし、それらのコピーをローカルキャッシュに格納します。
-
階層キーリングは、アセンブルされたブランチキーマテリアルと、ステップ 2 で識別された 16 バイトのソルトを使用して、データキーを暗号化した一意のラッピングキーを複製します。
-
階層型キーリングは、再生したラッピングキーを使用してデータキーを復号し、プレーンテキストのデータキーを返します。
復号の方法では、復号マテリアルとプレーンテキストのデータキーを使用して、暗号化されたメッセージを復号化します。詳細については、「 が暗号化されたメッセージを復 AWS Encryption SDK 号する方法」を参照してください。
前提条件
階層キーリングを作成して使用する前に、次の前提条件を満たしていることを確認してください。
必要なアクセス許可
AWS Encryption SDK は を必要とせず AWS アカウント 、 に依存しません AWS のサービス。ただし、階層キーリングを使用するには、キーストアの対称暗号化 AWS KMS key(複数可) に対する AWS アカウント と以下の最小限のアクセス許可が必要です。
ブランチキーとキーストアへのアクセスの制御の詳細については、「」を参照してください最小特権のアクセス許可の実装。
キャッシュを選択する
階層キーリングは、暗号化および復号オペレーションで使用されるブランチキーマテリアルをローカルにキャッシュ AWS KMS することで、 に対する呼び出しの数を減らします。階層キーリングを作成する前に、使用するキャッシュのタイプを決定する必要があります。デフォルトのキャッシュを使用するか、ニーズに合わせてキャッシュをカスタマイズできます。
階層キーリングは、次のキャッシュタイプをサポートしています。
デフォルトキャッシュ
ほとんどのユーザーにとって、Default キャッシュはスレッド要件を満たします。Default キャッシュは、高度にマルチスレッド化されている環境をサポートするように設計されています。ブランチキーマテリアルエントリの有効期限が切れると、デフォルトキャッシュは、ブランチキーマテリアルエントリが 10 秒前に期限切れになることを 1 つのスレッドに通知 AWS KMS することで、複数のスレッドが呼び出されるのを防ぎます。これにより、1 つのスレッドのみが にリクエストを送信 AWS KMS してキャッシュを更新します。
デフォルトキャッシュと StormTracking キャッシュは同じスレッドモデルをサポートしますが、デフォルトキャッシュを使用するにはエントリ容量を指定するだけで済みます。より詳細なキャッシュのカスタマイズを行うには、 を使用しますStormTracking キャッシュ。
ローカルキャッシュに保存できるブランチキーマテリアルエントリの数をカスタマイズする場合を除き、階層キーリングを作成するときにキャッシュタイプを指定する必要はありません。キャッシュタイプを指定しない場合、階層キーリングはデフォルトのキャッシュタイプを使用し、エントリ容量を 1000 に設定します。
デフォルトキャッシュをカスタマイズするには、次の値を指定します。
- Java
-
.cache(CacheType.builder()
.Default(DefaultCache.builder()
.entryCapacity(100)
.build())
- C# / .NET
-
CacheType defaultCache = new CacheType
{
Default = new DefaultCache{EntryCapacity = 100}
};
- Python
-
default_cache = CacheTypeDefault(
value=DefaultCache(
entry_capacity=100
)
)
- Rust
-
let cache: CacheType = CacheType::Default(
DefaultCache::builder()
.entry_capacity(100)
.build()?,
);
- Go
-
cache := mpltypes.CacheTypeMemberDefault{
Value: mpltypes.DefaultCache{
EntryCapacity: 100,
},
}
MultiThreadedキャッシュ
MultiThreadedキャッシュはマルチスレッド環境で安全に使用できますが、 AWS KMS または Amazon DynamoDB 呼び出しを最小限に抑える機能はありません。その結果、ブランチキーマテリアルのエントリの期限が切れると、すべてのスレッドに同時に通知されます。これにより、キャッシュを更新するための複数の AWS KMS 呼び出しが発生する可能性があります。
MultiThreaded キャッシュを使用するには、次の値を指定します。
- Java
-
.cache(CacheType.builder()
.MultiThreaded(MultiThreadedCache.builder()
.entryCapacity(100)
.entryPruningTailSize(1)
.build())
- C# / .NET
-
CacheType multithreadedCache = new CacheType
{
MultiThreaded = new MultiThreadedCache
{
EntryCapacity = 100,
EntryPruningTailSize = 1
}
};
- Python
-
multithreaded_cache = CacheTypeMultiThreaded(
value=MultiThreadedCache(
entry_capacity=100,
entry_pruning_tail_size=1
)
)
- Rust
-
CacheType::MultiThreaded(
MultiThreadedCache::builder()
.entry_capacity(100)
.entry_pruning_tail_size(1)
.build()?)
- Go
-
var entryPruningTailSize int32 = 1
cache := mpltypes.CacheTypeMemberMultiThreaded{
Value: mpltypes.MultiThreadedCache{
EntryCapacity: 100,
EntryPruningTailSize: &entryPruningTailSize,
},
}
StormTracking キャッシュ
StormTracking キャッシュは、高度にマルチスレッド化されている環境をサポートするように設計されています。ブランチキーマテリアルエントリの有効期限が切れると、StormTracking キャッシュは、ブランチキーマテリアルエントリの有効期限が切れることを 1 つのスレッドに通知 AWS KMS することで、複数のスレッドの呼び出しを防止します。これにより、1 つのスレッドのみが にリクエストを送信 AWS KMS してキャッシュを更新します。
StormTracking キャッシュを使用するには、次の値を指定します。
-
エントリキャパシティ: ローカルキャッシュに格納できるブランチキーマテリアルのエントリの数を制限します。
デフォルト値: 1000 エントリ
-
エントリのプルーニングテールのサイズ: 一度にプルーニングするブランチキーマテリアルのエントリの数を定義します。
デフォルトの値: 1 個のエントリ
-
猶予期間: 期限が切れる前にブランチキーマテリアルの更新を試行する秒数を定義します。
デフォルト値: 10 秒
-
猶予間隔: ブランチキーマテリアルの更新が試行される間隔の秒数を定義します。
デフォルト値: 1 秒
-
ファンアウト: ブランチキーマテリアルの更新の同時試行が可能な回数を定義します。
デフォルトの値: 20 回の試行
-
処理中の Time To Live (TTL): ブランチキーマテリアルの更新の試行がタイムアウトするまでの秒数を定義します。キャッシュが GetCacheEntry に応答して NoSuchEntry を返すたびに、同じキーが PutCache エントリを使用して書き込まれるまで、そのブランチキーは処理中であるとみなされます。
デフォルト値: 10 秒
-
スリープ: fanOutを超えた場合にスレッドがスリープするミリ秒数を定義します。
デフォルトの値: 20 ミリ秒
- Java
-
.cache(CacheType.builder()
.StormTracking(StormTrackingCache.builder()
.entryCapacity(100)
.entryPruningTailSize(1)
.gracePeriod(10)
.graceInterval(1)
.fanOut(20)
.inFlightTTL(10)
.sleepMilli(20)
.build())
- C# / .NET
-
CacheType stormTrackingCache = new CacheType
{
StormTracking = new StormTrackingCache
{
EntryCapacity = 100,
EntryPruningTailSize = 1,
FanOut = 20,
GraceInterval = 1,
GracePeriod = 10,
InFlightTTL = 10,
SleepMilli = 20
}
};
- Python
-
storm_tracking_cache = CacheTypeStormTracking(
value=StormTrackingCache(
entry_capacity=100,
entry_pruning_tail_size=1,
fan_out=20,
grace_interval=1,
grace_period=10,
in_flight_ttl=10,
sleep_milli=20
)
)
- Rust
-
CacheType::StormTracking(
StormTrackingCache::builder()
.entry_capacity(100)
.entry_pruning_tail_size(1)
.grace_period(10)
.grace_interval(1)
.fan_out(20)
.in_flight_ttl(10)
.sleep_milli(20)
.build()?)
- Go
-
var entryPruningTailSize int32 = 1
cache := mpltypes.CacheTypeMemberStormTracking{
Value: mpltypes.StormTrackingCache{
EntryCapacity: 100,
EntryPruningTailSize: &entryPruningTailSize,
GraceInterval: 1,
GracePeriod: 10,
FanOut: 20,
InFlightTTL: 10,
SleepMilli: 20,
},
}
共有キャッシュ
デフォルトでは、階層キーリングは、キーリングをインスタンス化するたびに新しいローカルキャッシュを作成します。ただし、共有キャッシュを使用すると、複数の階層キーリング間でキャッシュを共有できるため、メモリを節約できます。インスタンス化する階層キーリングごとに新しい暗号化マテリアルキャッシュを作成するのではなく、共有キャッシュは 1 つのキャッシュのみをメモリに保存します。このキャッシュは、それを参照するすべての階層キーリングで使用できます。共有キャッシュは、キーリング間での暗号化マテリアルの重複を回避することで、メモリ使用量を最適化するのに役立ちます。代わりに、階層キーリングは同じ基盤となるキャッシュにアクセスし、全体的なメモリフットプリントを削減できます。
共有キャッシュを作成する場合でも、キャッシュタイプを定義します。キャッシュタイプStormTracking キャッシュとして デフォルトキャッシュ、MultiThreadedキャッシュ、または を指定することも、互換性のあるカスタムキャッシュを置き換えることもできます。
パーティション
複数の階層キーリングで 1 つの共有キャッシュを使用できます。共有キャッシュを使用して階層キーリングを作成するときは、オプションのパーティション ID を定義できます。パーティション ID は、キャッシュに書き込む階層キーリングを区別します。2 つの階層キーリングが同じパーティション ID、logical key store name、ブランチキー ID を参照する場合、2 つのキーリングはキャッシュ内で同じキャッシュエントリを共有します。同じ共有キャッシュで異なるパーティション IDs を持つ 2 つの階層キーリングを作成すると、各キーリングは共有キャッシュ内の独自の指定されたパーティションからのみキャッシュエントリにアクセスします。パーティションは共有キャッシュ内の論理分割として機能し、各階層キーリングが他のパーティションに保存されているデータを妨害することなく、独自の指定されたパーティションで独立して動作できるようにします。
パーティション内のキャッシュエントリを再利用または共有する場合は、独自のパーティション ID を定義する必要があります。パーティション ID を階層キーリングに渡すと、キーリングは、ブランチキーマテリアルを再度取得して再承認するのではなく、共有キャッシュに既に存在するキャッシュエントリを再利用できます。パーティション ID を指定しない場合、階層キーリングをインスタンス化するたびに、一意のパーティション ID がキーリングに自動的に割り当てられます。
次の手順は、デフォルトのキャッシュタイプで共有キャッシュを作成し、階層キーリングに渡す方法を示しています。
-
マテリアルプロバイダーライブラリ CryptographicMaterialsCache (MPL) を使用して (CMC) を作成します。 https://github.com/aws/aws-cryptographic-material-providers-library
- Java
-
// Instantiate the MPL
final MaterialProviders matProv =
MaterialProviders.builder()
.MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
.build();
// Create a CacheType object for the Default cache
final CacheType cache =
CacheType.builder()
.Default(DefaultCache.builder().entryCapacity(100).build())
.build();
// Create a CMC using the default cache
final CreateCryptographicMaterialsCacheInput cryptographicMaterialsCacheInput =
CreateCryptographicMaterialsCacheInput.builder()
.cache(cache)
.build();
final ICryptographicMaterialsCache sharedCryptographicMaterialsCache =
matProv.CreateCryptographicMaterialsCache(cryptographicMaterialsCacheInput);
- C# / .NET
-
// Instantiate the MPL
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());
// Create a CacheType object for the Default cache
var cache = new CacheType { Default = new DefaultCache{EntryCapacity = 100} };
// Create a CMC using the default cache
var cryptographicMaterialsCacheInput = new CreateCryptographicMaterialsCacheInput {Cache = cache};
var sharedCryptographicMaterialsCache = materialProviders.CreateCryptographicMaterialsCache(cryptographicMaterialsCacheInput);
- Python
-
# Instantiate the MPL
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
config=MaterialProvidersConfig()
)
# Create a CacheType object for the default cache
cache: CacheType = CacheTypeDefault(
value=DefaultCache(
entry_capacity=100,
)
)
# Create a CMC using the default cache
cryptographic_materials_cache_input = CreateCryptographicMaterialsCacheInput(
cache=cache,
)
shared_cryptographic_materials_cache = mat_prov.create_cryptographic_materials_cache(
cryptographic_materials_cache_input
)
- Rust
-
// Instantiate the MPL
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
// Create a CacheType object for the default cache
let cache: CacheType = CacheType::Default(
DefaultCache::builder()
.entry_capacity(100)
.build()?,
);
// Create a CMC using the default cache
let shared_cryptographic_materials_cache: CryptographicMaterialsCacheRef = mpl.
create_cryptographic_materials_cache()
.cache(cache)
.send()
.await?;
- Go
-
import (
"context"
mpl "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated"
mpltypes "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes"
)
// Instantiate the MPL
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
if err != nil {
panic(err)
}
// Create a CacheType object for the default cache
cache := mpltypes.CacheTypeMemberDefault{
Value: mpltypes.DefaultCache{
EntryCapacity: 100,
},
}
// Create a CMC using the default cache
cmcCacheInput := mpltypes.CreateCryptographicMaterialsCacheInput{
Cache: &cache,
}
sharedCryptographicMaterialsCache, err := matProv.CreateCryptographicMaterialsCache(context.Background(), cmcCacheInput)
if err != nil {
panic(err)
}
-
共有キャッシュのCacheTypeオブジェクトを作成します。
ステップ 1 でsharedCryptographicMaterialsCache作成した を新しいCacheTypeオブジェクトに渡します。
- Java
-
// Create a CacheType object for the sharedCryptographicMaterialsCache
final CacheType sharedCache =
CacheType.builder()
.Shared(sharedCryptographicMaterialsCache)
.build();
- C# / .NET
-
// Create a CacheType object for the sharedCryptographicMaterialsCache
var sharedCache = new CacheType { Shared = sharedCryptographicMaterialsCache };
- Python
-
# Create a CacheType object for the shared_cryptographic_materials_cache
shared_cache: CacheType = CacheTypeShared(
value=shared_cryptographic_materials_cache
)
- Rust
-
// Create a CacheType object for the shared_cryptographic_materials_cache
let shared_cache: CacheType = CacheType::Shared(shared_cryptographic_materials_cache);
- Go
-
// Create a CacheType object for the shared_cryptographic_materials_cache
shared_cache := mpltypes.CacheTypeMemberShared{sharedCryptographicMaterialsCache}
-
ステップ 2 の sharedCache オブジェクトを階層キーリングに渡します。
共有キャッシュを使用して階層キーリングを作成する場合、オプションで を定義partitionIDして、複数の階層キーリング間でキャッシュエントリを共有できます。パーティション ID を指定しない場合、階層キーリングはキーリングに一意のパーティション ID を自動的に割り当てます。
同じパーティション ID、、logical key store nameブランチキー ID を参照する 2 つ以上のキーリングを作成すると、階層キーリングは共有キャッシュ内で同じキャッシュエントリを共有します。複数のキーリングで同じキャッシュエントリを共有しない場合は、階層キーリングごとに一意のパーティション ID を使用する必要があります。
次の例では、 でbranch key ID supplierキャッシュ制限が 600 秒の階層キーリングを作成します。次の階層キーリング設定で定義されている値の詳細については、「」を参照してください階層キーリングを作成する。
- Java
-
// Create the Hierarchical keyring
final CreateAwsKmsHierarchicalKeyringInput keyringInput =
CreateAwsKmsHierarchicalKeyringInput.builder()
.keyStore(keystore)
.branchKeyIdSupplier(branchKeyIdSupplier)
.ttlSeconds(600)
.cache(sharedCache)
.partitionID(partitionID)
.build();
final IKeyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
- C# / .NET
-
// Create the Hierarchical keyring
var createKeyringInput = new CreateAwsKmsHierarchicalKeyringInput
{
KeyStore = keystore,
BranchKeyIdSupplier = branchKeyIdSupplier,
Cache = sharedCache,
TtlSeconds = 600,
PartitionId = partitionID
};
var keyring = materialProviders.CreateAwsKmsHierarchicalKeyring(createKeyringInput);
- Python
-
# Create the Hierarchical keyring
keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput(
key_store=keystore,
branch_key_id_supplier=branch_key_id_supplier,
ttl_seconds=600,
cache=shared_cache,
partition_id=partition_id
)
hierarchical_keyring: IKeyring = mat_prov.create_aws_kms_hierarchical_keyring(
input=keyring_input
)
- Rust
-
// Create the Hierarchical keyring
let keyring1 = mpl
.create_aws_kms_hierarchical_keyring()
.key_store(key_store1)
.branch_key_id(branch_key_id.clone())
// CryptographicMaterialsCacheRef is an Rc (Reference Counted), so if you clone it to
// pass it to different Hierarchical Keyrings, it will still point to the same
// underlying cache, and increment the reference count accordingly.
.cache(shared_cache.clone())
.ttl_seconds(600)
.partition_id(partition_id.clone())
.send()
.await?;
- Go
-
// Create the Hierarchical keyring
hkeyringInput := mpltypes.CreateAwsKmsHierarchicalKeyringInput{
KeyStore: keyStore1,
BranchKeyId: &branchKeyId,
TtlSeconds: 600,
Cache: &shared_cache,
PartitionId: &partitionId,
}
keyring, err := matProv.CreateAwsKmsHierarchicalKeyring(context.Background(), hkeyringInput)
if err != nil {
panic(err)
}
階層キーリングを作成する
階層キーリングを作成するには、次の値を指定する必要があります。
-
キーストア名
キーストアとして機能するために作成した DynamoDB テーブルの名前、またはキーストア管理者。
-
キャッシュ制限 Time to Live (TTL)
ローカルキャッシュ内のブランチキーマテリアルエントリを使用できる時間 (期限切れになるまでの時間) (秒)。キャッシュ制限 TTL は、クライアントがブランチキーの使用を許可 AWS KMS するために を呼び出す頻度を指定します。この値はゼロより大きくなければなりません。キャッシュ制限 TTL の有効期限が切れると、エントリは提供されず、ローカルキャッシュから削除されます。
-
ブランチキーの識別子
キーストア内の 1 つのアクティブなブランチキーbranch-key-idを識別する を静的に設定するか、ブランチキー ID サプライヤーを指定できます。
ブランチキー ID サプライヤは、暗号化コンテキストに保存されているフィールドを使用して、レコードの復号に必要なブランチキーを決定します。
各テナントに独自のブランチキーがあるマルチテナントデータベースには、ブランチキー ID サプライヤーを使用することを強くお勧めします。ブランチキー ID サプライヤーを使用してブランチキー IDs のわかりやすい名前を作成し、特定のテナントの正しいブランチキー ID を簡単に認識できます。例えば、フレンドリ名を使用すると、ブランチキーを b3f61619-4d35-48ad-a275-050f87e15122 の代わりに tenant1 として参照できます。
復号オペレーションの場合、単一の階層キーリングを静的に設定して復号を単一のテナンシーに制限することも、ブランチキー ID サプライヤーを使用してレコードの復号を担当するテナンシーを識別することもできます。
-
(オプション) キャッシュ
キャッシュタイプまたはローカルキャッシュに格納できるブランチキーマテリアルエントリの数をカスタマイズする場合は、キーリングを初期化する際にキャッシュタイプとエントリキャパシティを指定します。
階層キーリングは、デフォルト、MultiThreaded、StormTracking、共有のキャッシュタイプをサポートしています。各キャッシュタイプを定義する方法の詳細と例については、「」を参照してくださいキャッシュを選択する。
キャッシュを指定しない場合、階層キーリングは、自動的に Default キャッシュタイプを使用し、エントリキャパシティを 1,000 に設定します。
-
(オプション) パーティション ID
を指定する場合は共有キャッシュ、オプションでパーティション ID を定義できます。パーティション ID は、キャッシュに書き込む階層キーリングを区別します。パーティション内のキャッシュエントリを再利用または共有する場合は、独自のパーティション ID を定義する必要があります。パーティション ID には任意の文字列を指定できます。パーティション ID を指定しない場合、作成時に一意のパーティション ID がキーリングに自動的に割り当てられます。
詳細については、「Partitions」を参照してください。
同じパーティション ID、、logical key store nameブランチキー ID を参照する 2 つ以上のキーリングを作成すると、階層キーリングは共有キャッシュ内で同じキャッシュエントリを共有します。複数のキーリングで同じキャッシュエントリを共有しない場合は、階層キーリングごとに一意のパーティション ID を使用する必要があります。
-
(オプション) 許可トークンのリスト
階層キーリング内の KMS キーへのアクセスを許可によって制御する場合は、キーリングを初期化する際に必要なすべての許可トークンを指定する必要があります。
次の例は、静的ブランチキー ID、、デフォルトキャッシュキャッシュ制限 TTL が 600 秒の階層キーリングを作成する方法を示しています。
- Java
-
final MaterialProviders matProv = MaterialProviders.builder()
.MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
.build();
final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder()
.keyStore(branchKeyStoreName)
.branchKeyId(branch-key-id)
.ttlSeconds(600)
.build();
final Keyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
- C# / .NET
-
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsHierarchicalKeyringInput
{
KeyStore = keystore,
BranchKeyId = branch-key-id,
TtlSeconds = 600
};
var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
- Python
-
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
config=MaterialProvidersConfig()
)
keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput(
key_store=keystore,
branch_key_id=branch_key_id,
ttl_seconds=600
)
hierarchical_keyring: IKeyring = mat_prov.create_aws_kms_hierarchical_keyring(
input=keyring_input
)
- Rust
-
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
let hierarchical_keyring = mpl
.create_aws_kms_hierarchical_keyring()
.key_store(key_store.clone())
.branch_key_id(branch_key_id)
.ttl_seconds(600)
.send()
.await?;
- Go
-
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
if err != nil {
panic(err)
}
hkeyringInput := mpltypes.CreateAwsKmsHierarchicalKeyringInput{
KeyStore: keyStore,
BranchKeyId: &branchKeyID,
TtlSeconds: 600,
}
hKeyRing, err := matProv.CreateAwsKmsHierarchicalKeyring(context.Background(), hkeyringInput)
if err != nil {
panic(err)
}
次の手順は、ブランチキー ID サプライヤーを使用して階層キーリングを作成する方法を示しています。
-
ブランチキー ID サプライヤーを作成する
次の例では、暗号化時または復号時に暗号化コンテキストを使用して各テナントのブランチキー ID を選択するブランチキー ID サプライヤーを定義します。各言語での実際の実装については、以下を参照してください。
- Java
-
// Define a branch key ID supplier that uses the encryption context to
// select a branch key ID for each tenant.
public class ExampleBranchKeyIdSupplier implements IBranchKeyIdSupplier {
private static String branchKeyIdForTenantA;
private static String branchKeyIdForTenantB;
public ExampleBranchKeyIdSupplier(String tenant1Id, String tenant2Id) {
this.branchKeyIdForTenantA = tenant1Id;
this.branchKeyIdForTenantB = tenant2Id;
}
@Override
public GetBranchKeyIdOutput GetBranchKeyId(GetBranchKeyIdInput input) {
Map<String, String> encryptionContext = input.encryptionContext();
if (!encryptionContext.containsKey("tenant")) {
throw new IllegalArgumentException(
"EncryptionContext invalid, does not contain expected tenant key value pair.");
}
String tenantKeyId = encryptionContext.get("tenant");
String branchKeyId;
if (tenantKeyId.equals("TenantA")) {
branchKeyId = branchKeyIdForTenantA;
} else if (tenantKeyId.equals("TenantB")) {
branchKeyId = branchKeyIdForTenantB;
} else {
throw new IllegalArgumentException("Item does not contain valid tenant ID");
}
return GetBranchKeyIdOutput.builder().branchKeyId(branchKeyId).build();
}
}
// Create the branch key ID supplier
final IBranchKeyIdSupplier branchKeyIdSupplier = new ExampleBranchKeyIdSupplier(
branch-key-ID-tenantA, branch-key-ID-tenantB);
- C# / .NET
-
// Define a branch key ID supplier that uses the encryption context to
// select a branch key ID for each tenant.
public class ExampleBranchKeySupplier : BranchKeyIdSupplierBase {
private string branchKeyTenantA;
private string branchKeyTenantB;
public ExampleBranchKeySupplier(string branchKeyTenantA, string branchKeyTenantB) {
this.branchKeyTenantA = branchKeyTenantA;
this.branchKeyTenantB = branchKeyTenantB;
}
// The encryption context is used to determine the Branch Key ID.
protected override GetBranchKeyIdOutput _GetBranchKeyId(GetBranchKeyIdInput input) {
Dictionary<string, string> encryptionContext = input.EncryptionContext;
if (!encryptionContext.ContainsKey("tenant")) {
throw new Exception("EncryptionContext invalid, does not contain expected tenant key value pair.");
}
string tenant = encryptionContext["tenant"];
if (tenant.Equals("TenantA")) {
return new GetBranchKeyIdOutput { BranchKeyId = branchKeyTenantA };
}
if (tenant.Equals("TenantB")) {
return new GetBranchKeyIdOutput { BranchKeyId = branchKeyTenantB };
}
throw new Exception("Item does not have a valid tenantID.");
}
}
// Create the branch key ID supplier
var branchKeyIdSupplier = new ExampleBranchKeySupplier(
branch-key-ID-tenantA, branch-key-ID-tenantB);
- Python
-
# Define a branch key ID supplier that uses the encryption context to
# select a branch key ID for each tenant.
class ExampleBranchKeyIdSupplier(IBranchKeyIdSupplier):
branch_key_id_for_tenant_A: str
branch_key_id_for_tenant_B: str
def __init__(self, tenant_1_id, tenant_2_id):
self.branch_key_id_for_tenant_A = tenant_1_id
self.branch_key_id_for_tenant_B = tenant_2_id
def get_branch_key_id(
self, param: GetBranchKeyIdInput
) -> GetBranchKeyIdOutput:
encryption_context = param.encryption_context
if "tenant" not in encryption_context:
raise ValueError("EncryptionContext invalid, does not contain expected tenant key value pair.")
tenant_key_id = encryption_context.get("tenant")
if tenant_key_id == "TenantA":
branch_key_id = self.branch_key_id_for_tenant_A
elif tenant_key_id == "TenantB":
branch_key_id = self.branch_key_id_for_tenant_B
else:
raise ValueError(f"Item does not contain valid tenant ID: {tenant_key_id=}")
return GetBranchKeyIdOutput(branch_key_id=branch_key_id)
# Create the branch key ID supplier
branch_key_id_supplier: IBranchKeyIdSupplier = ExampleBranchKeyIdSupplier(
tenant_1_id=branch_key_id_a,
tenant_2_id=branch_key_id_b,
)
- Rust
-
// Define a branch key ID supplier that uses the encryption context to
// select a branch key ID for each tenant.
pub struct ExampleBranchKeyIdSupplier {
branch_key_id_for_tenant_a: String,
branch_key_id_for_tenant_b: String,
}
impl ExampleBranchKeyIdSupplier {
pub fn new(tenant_a_id: &str, tenant_b_id: &str) -> Self {
Self {
branch_key_id_for_tenant_a: tenant_a_id.to_string(),
branch_key_id_for_tenant_b: tenant_b_id.to_string(),
}
}
}
// The encryption context is used to determine the Branch Key ID.
impl BranchKeyIdSupplier for ExampleBranchKeyIdSupplier {
fn get_branch_key_id(&self, input: GetBranchKeyIdInput) -> Result<GetBranchKeyIdOutput, Error> {
let encryption_context: HashMap<String, String> = input.encryption_context.unwrap();
if !encryption_context.contains_key("tenant") {
return Err(Error::AwsCryptographicMaterialProvidersException {
message: "EncryptionContext invalid, does not contain expected tenant key value pair.".to_string(),
});
}
let tenant_key_id: &str = encryption_context["tenant"].as_str();
if tenant_key_id == "TenantA" {
Ok(GetBranchKeyIdOutput::builder()
.branch_key_id(self.branch_key_id_for_tenant_a.clone())
.build()
.unwrap())
} else if tenant_key_id == "TenantB" {
Ok(GetBranchKeyIdOutput::builder()
.branch_key_id(self.branch_key_id_for_tenant_b.clone())
.build()
.unwrap())
} else {
Err(Error::AwsCryptographicMaterialProvidersException {
message: "Item does not contain valid tenant ID.".to_string(),
})
}
}
}
// Create the branch key ID supplier
let branch_key_id_supplier = ExampleBranchKeyIdSupplier::new(
&branch_key_id_a,
&branch_key_id_b,
);
- Go
-
// Define a branch key ID supplier that uses the encryption context to
// select a branch key ID for each tenant.
type branchKeySupplier struct {
branchKeyA string
branchKeyB string
}
// The encryption context is used to determine the Branch Key ID.
func (b *branchKeySupplier) GetBranchKeyId(input mpltypes.GetBranchKeyIdInput) (*mpltypes.GetBranchKeyIdOutput, error) {
ec := input.EncryptionContext
if value, exists := ec["tenant"]; !exists || value == "" {
return nil, fmt.Errorf("EncryptionContext invalid, does not contain expected tenant key value pair.")
}
branchKeyIdentifier := ec["tenant"]
if branchKeyIdentifier == "TenantA" {
return &mpltypes.GetBranchKeyIdOutput{BranchKeyId: b.branchKeyA}, nil
} else if branchKeyIdentifier == "TenantB" {
return &mpltypes.GetBranchKeyIdOutput{BranchKeyId: b.branchKeyB}, nil
} else {
return &mpltypes.GetBranchKeyIdOutput{}, fmt.Errorf("unknown branch key identifier")
}
}
// Create the branch key ID supplier
keySupplier := branchKeySupplier{branchKeyA: branchKeyA, branchKeyB: branchKeyB}
-
階層キーリングを作成する
次の例では、ステップ 1 で作成したブランチキー ID サプライヤー、キャッシュ制限 TLL が 600 秒、最大キャッシュサイズが 1000 の階層キーリングを初期化します。
- Java
-
final MaterialProviders matProv = MaterialProviders.builder()
.MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
.build();
final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder()
.keyStore(keystore)
.branchKeyIdSupplier(branchKeyIdSupplier)
.ttlSeconds(600)
.cache(CacheType.builder() //OPTIONAL
.Default(DefaultCache.builder()
.entryCapacity(100)
.build())
.build();
final Keyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
- C# / .NET
-
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsHierarchicalKeyringInput
{
KeyStore = keystore,
BranchKeyIdSupplier = branchKeyIdSupplier,
TtlSeconds = 600,
Cache = new CacheType
{
Default = new DefaultCache { EntryCapacity = 100 }
}
};
var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
- Python
-
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
config=MaterialProvidersConfig()
)
keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput(
key_store=keystore,
branch_key_id_supplier=branch_key_id_supplier,
ttl_seconds=600,
cache=CacheTypeDefault(
value=DefaultCache(
entry_capacity=100
)
),
)
hierarchical_keyring: IKeyring = mat_prov.create_aws_kms_hierarchical_keyring(
input=keyring_input
)
- Rust
-
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
let hierarchical_keyring = mpl
.create_aws_kms_hierarchical_keyring()
.key_store(key_store.clone())
.branch_key_id_supplier(branch_key_id_supplier)
.ttl_seconds(600)
.send()
.await?;
- Go
-
hkeyringInput := mpltypes.CreateAwsKmsHierarchicalKeyringInput{
KeyStore: keyStore,
BranchKeyIdSupplier: &keySupplier,
TtlSeconds: 600,
}
hKeyRing, err := matProv.CreateAwsKmsHierarchicalKeyring(context.Background(), hkeyringInput)
if err != nil {
panic(err)
}