

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# AWS KMS Hierarchische Schlüsselringe
<a name="use-hierarchical-keyring"></a>

Mit dem AWS KMS hierarchischen Schlüsselbund können Sie Ihr kryptografisches Material mit einem KMS-Schlüssel mit symmetrischer Verschlüsselung schützen, ohne AWS KMS jedes Mal anrufen zu müssen, wenn Sie Daten ver- oder entschlüsseln. Es ist eine gute Wahl für Anwendungen, bei denen die Anzahl der Aufrufe minimiert werden muss AWS KMS, und für Anwendungen, die einige kryptografische Materialien wiederverwenden können, ohne ihre Sicherheitsanforderungen zu verletzen.

Beim hierarchischen Schlüsselbund handelt es sich um eine Lösung zum Zwischenspeichern kryptografischer Materialien, die die Anzahl der AWS KMS Aufrufe reduziert, indem AWS KMS geschützte * Zweigschlüssel * verwendet werden, die in einer Amazon DynamoDB-Tabelle gespeichert sind, und anschließend das für Verschlüsselungs- und Entschlüsselungsvorgänge verwendete Zweigschlüsselmaterial lokal zwischenspeichert. Die DynamoDB-Tabelle dient als Schlüsselspeicher, der Zweigschlüssel verwaltet und schützt. Sie speichert den aktiven Zweigschlüssel und alle früheren Versionen des Zweigschlüssels. Der * aktive * Filialschlüssel ist die neueste Version des Zweigschlüssels. Der hierarchische Schlüsselbund verwendet einen eindeutigen Datenschlüssel, um jede Nachricht zu verschlüsseln. Er verschlüsselt jeden Datenverschlüsselungsschlüssel für jede Verschlüsselungsanforderung und verschlüsselt jeden Datenverschlüsselungsschlüssel mit einem eindeutigen Umhüllungsschlüssel, der vom aktiven Zweigschlüssel abgeleitet wird. Der hierarchische Schlüsselbund hängt von der Hierarchie ab, die zwischen aktiven Zweigschlüsseln und ihren abgeleiteten Umhüllungsschlüsseln eingerichtet wurde.

Der hierarchische Schlüsselbund verwendet in der Regel jede Zweigschlüsselversion, um mehrere Anforderungen zu erfüllen. Sie steuern jedoch, in welchem Umfang aktive Abzweigschlüssel wiederverwendet werden, und bestimmen, wie oft der aktive Abzweigschlüssel rotiert wird. Die aktive Version der Abzweigtaste bleibt aktiv, bis Sie sie [Drehe deinen aktiven Filialschlüssel](rotate-branch-key.md) drehen. Frühere Versionen des aktiven Zweigschlüssels werden nicht für Verschlüsselungsvorgänge verwendet, können aber trotzdem abgefragt und bei Entschlüsselungsvorgängen verwendet werden.

Wenn Sie den hierarchischen Schlüsselbund instanziieren, wird ein lokaler Cache erstellt. Sie geben ein [ Cache-Limit an](#cache-limit), das die maximale Zeitdauer definiert, für die die Branch-Key-Materialien im lokalen Cache gespeichert werden, bevor sie ablaufen und aus dem Cache entfernt werden. Der hierarchische Schlüsselbund führt einen AWS KMS Aufruf durch, um den Zweigschlüssel zu entschlüsseln und die Zweigschlüsselmaterialien zusammenzustellen, wenn a zum ersten Mal in einer Operation angegeben `branch-key-id` wird. Anschließend werden die Zweigschlüsselmaterialien im lokalen Cache gespeichert und für alle Verschlüsselungs- und Entschlüsselungsvorgänge, die dies angeben, wiederverwendet, bis das Cache-Limit abläuft. `branch-key-id` Das Speichern von Zweigschlüsselmaterial im lokalen Cache reduziert die Anzahl der Aufrufe. AWS KMS Stellen Sie sich beispielsweise ein Cache-Limit von 15 Minuten vor. Wenn Sie 10.000 Verschlüsselungsvorgänge innerhalb dieses Cache-Limits ausführen, [ müsste der ](use-kms-keyring.md) herkömmliche AWS KMS Schlüsselbund 10.000 AWS KMS Aufrufe tätigen, um 10.000 Verschlüsselungsvorgänge abzuwickeln. Wenn Sie einen aktiven Schlüsselbund haben`branch-key-id`, muss der hierarchische Schlüsselbund nur einen AWS KMS Aufruf tätigen, um 10.000 Verschlüsselungsvorgänge abzuwickeln.

Der lokale Cache trennt Verschlüsselungsmaterial von Entschlüsselungsmaterial. Das Verschlüsselungsmaterial wird aus dem aktiven Zweigschlüssel zusammengestellt und für alle Verschlüsselungsvorgänge wiederverwendet, bis das Cache-Limit abläuft. Die Entschlüsselungsmaterialien werden aus der Zweigschlüssel-ID und der Version zusammengestellt, die in den Metadaten des verschlüsselten Felds identifiziert sind. Sie werden für alle Entschlüsselungsvorgänge im Zusammenhang mit der Zweigschlüssel-ID und Version wiederverwendet, bis das Cache-Limit abläuft. Der lokale Cache kann mehrere Versionen desselben Zweigschlüssels gleichzeitig speichern. Wenn der lokale Cache für die Verwendung von a konfiguriert ist[branch key ID supplier](#branch-key-id-supplier), kann er auch Filialschlüsselmaterial aus mehreren aktiven Zweigschlüsseln gleichzeitig speichern.

**Anmerkung**  
Alle Erwähnungen des * Begriffs Hierarchischer Schlüsselbund * im AWS Encryption SDK beziehen sich auf den AWS KMS Hierarchischen Schlüsselbund.

**Kompatibilität mit Programmiersprachen**  
Der hierarchische Schlüsselbund wird von den folgenden Programmiersprachen und Versionen unterstützt:
+ Version 3. *x * des AWS-Verschlüsselungs-SDK for Java
+ Version 4. *x * und höher von AWS Encryption SDK für .NET
+ Version 4. *x * von AWS-Verschlüsselungs-SDK for Python, wenn es mit der optionalen MPL-Abhängigkeit verwendet wird.
+ Version 1. *x * der AWS Encryption SDK für Rust
+ Version 0.1. *x * oder höher der AWS Encryption SDK für Go
+ Version 4.1. *x * und später der AWS-Verschlüsselungs-SDK for JavaScript Form JavaScript Node.js.
  + Der AWS KMS hierarchische Schlüsselbund wird im for-Browser nicht unterstützt. AWS-Verschlüsselungs-SDK for JavaScript JavaScript Den aktuellen Status und die Einschränkungen finden Sie im [https://github.com/aws/aws-encryption-sdk-javascript/](https://github.com/aws/aws-encryption-sdk-javascript/) aws-encryption-sdk-javascript-Repository unter. GitHub

**Topics**
+ [Funktionsweise](#how-hierarchical-keyring-works)
+ [Voraussetzungen](#hierarchical-keyring-prereqs)
+ [Erforderliche Berechtigungen](#hierarchical-keyring-permissions)
+ [Wählen Sie einen Cache](#hierarchical-keyring-caches)
+ [Erstellen Sie einen hierarchischen Schlüsselbund](#initialize-hierarchical-keyring)

## Funktionsweise
<a name="how-hierarchical-keyring-works"></a>

In den folgenden exemplarischen Vorgehensweisen wird beschrieben, wie der hierarchische Schlüsselbund Verschlüsselungs- und Entschlüsselungsmaterial zusammenstellt, sowie die verschiedenen Aufrufe, die der Schlüsselbund für Verschlüsselungs- und Entschlüsselungsvorgänge ausführt. Technische Details zu den Verfahren zur Ableitung von Wrapping-Schlüsseln und zur Verschlüsselung von Klartext-Datenschlüsseln finden Sie unter Technische Details zum hierarchischen Schlüsselbund. [AWS KMS](hierarchical-keyring-details.md)

**Verschlüsseln und signieren**  
In der folgenden exemplarischen Vorgehensweise wird beschrieben, wie der hierarchische Schlüsselbund Verschlüsselungsmaterialien zusammenstellt und daraus einen eindeutigen Umschließungsschlüssel ableitet. 

1. Bei der Verschlüsselungsmethode wird der hierarchische Schlüsselbund nach Verschlüsselungsmaterial gefragt. Der Schlüsselbund generiert einen Klartext-Datenschlüssel und prüft dann, ob im lokalen Cache gültige Verzweigungsmaterialien vorhanden sind, um den Wrapping-Schlüssel zu generieren. Wenn gültige Materialien für die Zweigschlüssel vorhanden sind, fährt der Schlüsselbund mit Schritt 4 fort**. ** 

1. Wenn keine gültigen Materialien für Zweigschlüssel vorhanden sind, fragt der hierarchische Schlüsselbund den Schlüsselspeicher nach dem aktiven Zweigschlüssel ab.

   1. Der Schlüsselspeicher ruft AWS KMS zur Entschlüsselung des aktiven Zweigschlüssels auf und gibt den aktiven Zweigschlüssel im Klartext zurück. Daten, die den aktiven Zweigschlüssel identifizieren, werden serialisiert, um zusätzliche authentifizierte Daten (AAD) im Entschlüsselungsaufruf von bereitzustellen. AWS KMS

   1. Der Schlüsselspeicher gibt den Zweigschlüssel im Klartext und die ihn identifizierenden Daten zurück, z. B. die Version des Zweigschlüssels.

1. Der hierarchische Schlüsselbund stellt die Schlüsselmaterialien der Zweige zusammen (die Version des Zweigschlüssels im Klartext und die Version des Zweigschlüssels) und speichert eine Kopie davon im lokalen Cache.

1. Der hierarchische Schlüsselbund leitet aus dem Zweigschlüssel im Klartext und einem zufälligen 16-Byte-Salt einen eindeutigen Umbruchsschlüssel ab. Er verwendet den abgeleiteten Wrapping-Schlüssel, um eine Kopie des Klartext-Datenschlüssels zu verschlüsseln.

Die Verschlüsselungsmethode verwendet die Verschlüsselungsmaterialien, um die Daten zu verschlüsseln. Weitere Informationen finden Sie unter [ So werden AWS Encryption SDK Daten verschlüsselt. ](how-it-works.md#encrypt-workflow)

**Entschlüsseln und verifizieren**  
In der folgenden exemplarischen Vorgehensweise wird beschrieben, wie der hierarchische Schlüsselbund Entschlüsselungsmaterial zusammenstellt und den verschlüsselten Datenschlüssel entschlüsselt.

1. Die Entschlüsselungsmethode identifiziert den verschlüsselten Datenschlüssel aus der verschlüsselten Nachricht und übergibt ihn an den hierarchischen Schlüsselbund.

1. Der hierarchische Schlüsselbund deserialisiert Daten, die den verschlüsselten Datenschlüssel identifizieren, einschließlich der Version des Zweigschlüssels, des 16-Byte-Salt und anderer Informationen, die beschreiben, wie der Datenschlüssel verschlüsselt wurde.

   Weitere Informationen finden Sie unter [AWS KMS Technische Details zum hierarchischen Schlüsselbund](hierarchical-keyring-details.md).

1. Der hierarchische Schlüsselbund überprüft, ob im lokalen Cache gültige Zweigschlüsselmaterialien vorhanden sind, die der in Schritt 2 identifizierten Version des Zweigschlüssels entsprechen. ** ** Wenn gültige Materialien für Zweigschlüssel vorhanden sind, fährt der Schlüsselbund mit Schritt 6 fort**. **

1. Wenn keine gültigen Materialien für Zweigschlüssel vorhanden sind, fragt der hierarchische Schlüsselbund den Schlüsselspeicher nach dem Zweigschlüssel ab, der der in ** Schritt 2 identifizierten Version des Zweigschlüssels entspricht. **

   1. Der Schlüsselspeicher ruft AWS KMS auf, um den Zweigschlüssel zu entschlüsseln, und gibt den aktiven Zweigschlüssel im Klartext zurück. Daten, die den aktiven Zweigschlüssel identifizieren, werden serialisiert, um zusätzliche authentifizierte Daten (AAD) im Entschlüsselungsaufruf von bereitzustellen. AWS KMS

   1. Der Schlüsselspeicher gibt den Zweigschlüssel im Klartext und die ihn identifizierenden Daten zurück, z. B. die Version des Zweigschlüssels.

1. Der hierarchische Schlüsselbund stellt die Schlüsselmaterialien der Zweige zusammen (die Version des Zweigschlüssels im Klartext und die Version des Zweigschlüssels) und speichert eine Kopie davon im lokalen Cache.

1. Der hierarchische Schlüsselbund verwendet das zusammengestellte Zweigschlüsselmaterial und das in ** Schritt 2 identifizierte 16-Byte-Salt, um den eindeutigen Wrapping-Schlüssel ** zu reproduzieren, der den Datenschlüssel verschlüsselt hat.

1. Der hierarchische Schlüsselbund verwendet den reproduzierten Wrapping-Schlüssel zur Entschlüsselung des Datenschlüssels und gibt den Klartext-Datenschlüssel zurück.

Die Entschlüsselungsmethode verwendet das Entschlüsselungsmaterial und den Klartext-Datenschlüssel, um die verschlüsselte Nachricht zu entschlüsseln. Weitere Informationen finden Sie unter [ So AWS Encryption SDK entschlüsselt der eine verschlüsselte Nachricht. ](how-it-works.md#decrypt-workflow)

## Voraussetzungen
<a name="hierarchical-keyring-prereqs"></a>

Bevor Sie einen hierarchischen Schlüsselbund erstellen und verwenden, stellen Sie sicher, dass die folgenden Voraussetzungen erfüllt sind.
+ Sie oder Ihr Schlüsselspeicheradministrator haben [ einen Schlüsselspeicher ](create-keystore.md) und mindestens einen aktiven Filialschlüssel [ erstellt. ](create-branch-keys.md)
+ Sie haben Ihre Key-Store-Aktionen [ konfiguriert](keystore-actions.md#config-keystore-actions).
**Anmerkung**  
Wie Sie Ihre Schlüsselspeicheraktionen konfigurieren, bestimmt, welche Operationen Sie ausführen können und welche KMS-Schlüssel der hierarchische Schlüsselbund verwenden kann. Weitere Informationen finden Sie unter [ Schlüsselspeicher-Aktionen. ](keystore-actions.md)
+ Sie verfügen über die erforderlichen AWS KMS Berechtigungen, um auf den Schlüsselspeicher und die Filialschlüssel zuzugreifen und diese zu verwenden. Weitere Informationen finden Sie unter [Erforderliche Berechtigungen](#hierarchical-keyring-permissions).
+ Sie haben die unterstützten Cachetypen überprüft und den Cachetyp konfiguriert, der Ihren Anforderungen am besten entspricht. Weitere Informationen finden Sie unter [Wählen Sie einen Cache](#hierarchical-keyring-caches).

## Erforderliche Berechtigungen
<a name="hierarchical-keyring-permissions"></a>

Das erfordert AWS Encryption SDK keinen AWS-Konto und es hängt von keinem ab AWS-Service. Um einen hierarchischen Schlüsselbund verwenden zu können, benötigen Sie jedoch eine AWS-Konto und die folgenden Mindestberechtigungen für die symmetrische (n) Verschlüsselung AWS KMS key(en) in Ihrem Schlüsselspeicher. 
+ Um Daten mit dem hierarchischen Schlüsselbund zu verschlüsseln und zu entschlüsseln, benötigen Sie kms:Decrypt. [https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)
+ Um [ Zweigschlüssel zu [ erstellen ](create-branch-keys.md) und zu ](rotate-branch-key.md) rotieren, benötigen Sie kms: und kms:. [ GenerateDataKeyWithoutPlaintext ](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) [ ReEncrypt ](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html)

**Erforderliche Amazon DynamoDB-Berechtigungen für die Schlüsselspeichertabelle**  
Die Principals, die mit Ihrem Schlüsselspeicher interagieren, benötigen ebenfalls Berechtigungen für die DynamoDB-Tabelle. Der Satz von Berechtigungen hängt von der Rolle ab.

**Benutzer des Schlüsselspeichers**  
Ein Schlüsselspeicher-Benutzer ist der Prinzipal, der den hierarchischen Schlüsselbund zum Verschlüsseln und Entschlüsseln von Daten verwendet. Ein Schlüsselspeicher-Benutzer benötigt [ dynamodb: GetItem ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) in der Schlüsselspeichertabelle.

**Administrator des Schlüsselspeichers**  
Ein Schlüsselspeicheradministrator ist der Prinzipal, der [ Zweigschlüssel [ erstellt ](create-branch-keys.md) und ](rotate-branch-key.md) rotiert. Ein Schlüsselspeicheradministrator benötigt die folgenden Berechtigungen für die Schlüsselspeichertabelle:  
+ Zum Lesen: [ dynamodb: GetItem ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) und dynamodb:. ConditionCheckItem
+ Für transaktionale Schreibvorgänge: dynamodb: und dynamodb:. ConditionCheckItem [ PutItem ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) Der hierarchische Schlüsselbundspeicher führt Schreibvorgänge durch. Sie können die [ TransactWriteItems ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html) Schreibberechtigungen für diesen Vorgang mit einer Bedingung einschränken. `dynamodb:EnclosingOperation`

Weitere Informationen zur Steuerung des Zugriffs auf Ihre Filialschlüssel und Ihren Schlüsselspeicher finden Sie unter. [Implementieren der geringsten Berechtigungen](keystore-least-privilege.md)

## Wählen Sie einen Cache
<a name="hierarchical-keyring-caches"></a>

Der hierarchische Schlüsselbund reduziert die Anzahl der Aufrufe, AWS KMS indem das bei Ver- und Entschlüsselungsvorgängen verwendete Zweigschlüsselmaterial lokal zwischengespeichert wird. Bevor Sie Ihren hierarchischen Schlüsselbund [ erstellen, müssen Sie entscheiden](#initialize-hierarchical-keyring), welche Art von Cache Sie verwenden möchten. Sie können den Standard-Cache verwenden oder den Cache an Ihre Bedürfnisse anpassen.

Der hierarchische Schlüsselbund unterstützt die folgenden Cachetypen:
+ [Standard-Cache](#cache-default)
+ [MultiThreaded Cache](#cache-multithreaded)
+ [StormTracking zwischenspeichern](#cache-stormtracking)
+ [Gemeinsam genutzter Cache](#cache-shared)

**Wichtig**  
Alle unterstützten Cachetypen sind für die Unterstützung von Multithread-Umgebungen konzipiert.  
In Kombination mit dem unterstützt der AWS-Verschlüsselungs-SDK for Python hierarchische Schlüsselbund jedoch keine Multithread-Umgebungen. Weitere Informationen finden Sie in der [ README.rst ](https://github.com/aws/aws-cryptographic-material-providers-library/blob/main/AwsCryptographicMaterialProviders/runtimes/python/README.rst) Python-Datei im Repository [https://github.com/aws/aws-cryptographic-material-providers-library/tree/main](https://github.com/aws/aws-cryptographic-material-providers-library/tree/main) aws-cryptographic-material-providers-library unter. GitHub

### Standard-Cache
<a name="cache-default"></a>

Für die meisten Benutzer erfüllt der Standard-Cache ihre Threading-Anforderungen. Der Standard-Cache ist so konzipiert, dass er Umgebungen mit hohem Multithreading-Anteil unterstützt. Wenn ein Eintrag für Branch Key Materials abläuft, verhindert der Standard-Cache den Aufruf mehrerer Threads, AWS KMS indem er einen Thread darüber informiert, dass der Eintrag für Branch Key Materials 10 Sekunden im Voraus abläuft. Dadurch wird sichergestellt, dass nur ein Thread eine Anfrage AWS KMS zur Aktualisierung des Caches sendet.

Der Default und die StormTracking Caches unterstützen dasselbe Threading-Modell, aber Sie müssen nur die Eingangskapazität angeben, um den Standard-Cache verwenden zu können. Für detailliertere Cache-Anpassungen verwenden Sie die. [StormTracking zwischenspeichern](#cache-stormtracking)

Sofern Sie nicht die Anzahl der Materialeinträge für Branch Key anpassen möchten, die im lokalen Cache gespeichert werden können, müssen Sie bei der Erstellung des hierarchischen Schlüsselbundes keinen Cachetyp angeben. Wenn Sie keinen Cachetyp angeben, verwendet der hierarchische Schlüsselbund den Standard-Cachetyp und legt die Eintragskapazität auf 1000 fest. 

Um den Standard-Cache anzupassen, geben Sie die folgenden Werte an:
+ **Eintragskapazität**: begrenzt die Anzahl der Materialeinträge für Branch Key, die im lokalen Cache gespeichert werden können.

------
#### [ 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 Cache
<a name="cache-multithreaded"></a>

Der MultiThreaded Cache kann sicher in Multithread-Umgebungen verwendet werden, bietet jedoch keine Funktionen zur Minimierung AWS KMS von Amazon DynamoDB-Aufrufen. Daher werden alle Threads gleichzeitig benachrichtigt, wenn ein Eintrag zu Branch Key Materials abläuft. Dies kann zu mehreren AWS KMS Aufrufen zur Aktualisierung des Caches führen.

Um den MultiThreaded Cache zu verwenden, geben Sie die folgenden Werte an:
+ **Eintragskapazität**: begrenzt die Anzahl der Einträge für Branch Key Materials, die im lokalen Cache gespeichert werden können.
+ **Endgröße beim Löschen von Einträgen**: Definiert die Anzahl der Einträge, die gelöscht werden sollen, wenn die Eingangskapazität erreicht ist.

------
#### [ 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 zwischenspeichern
<a name="cache-stormtracking"></a>

Der StormTracking Cache ist so konzipiert, dass er Umgebungen mit hohem Multithreading-Anteil unterstützt. Wenn ein Eintrag für Branch Key Materials abläuft, verhindert der StormTracking Cache, dass mehrere Threads aufgerufen AWS KMS werden, indem er einen Thread im Voraus darüber informiert, dass der Branch Key Materials Eintrag abläuft. Dadurch wird sichergestellt, dass nur ein Thread eine Anfrage zur Aktualisierung des Caches AWS KMS an sendet. Weitere Informationen finden Sie unter [ Storm Tracking Cryptographic Materials Cache ](https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/storm-tracking-cryptographic-materials-cache.md) im Repository GitHub aws-encryption-sdk-Spezifikation.



Um den Cache zu verwenden, geben Sie die folgenden Werte an StormTracking :
+ **Eintragskapazität**: begrenzt die Anzahl der Einträge für Branch Key Materials, die im lokalen Cache gespeichert werden können.

  Standardwert: 1000 Einträge
+ **Schnittgröße des Eintrags**: Definiert die Anzahl der Einträge für wichtige Materialien aus den Zweigen, die gleichzeitig beschnitten werden sollen.

  Standardwert: 1 Eintrag
+ **Übergangszeit**: Definiert die Anzahl der Sekunden vor Ablauf, in denen versucht wird, die wichtigsten Materialien der Filiale zu aktualisieren.

  Standardwert: 10 Sekunden
+ **Übergangsintervall**: Definiert die Anzahl der Sekunden zwischen Versuchen, die Materialien für die Zweige zu aktualisieren.

  Standardwert: 1 Sekunde
+ **Fan-Out**: Definiert die Anzahl der gleichzeitigen Versuche, die wichtigsten Materialien der Branche zu aktualisieren.

  Standardwert: 20 Versuche
+ **In Flight Time to Live (TTL)**: Definiert die Anzahl der Sekunden, bis beim Versuch, die Materialien der Branch Key zu aktualisieren, das Zeitlimit überschritten wird. Jedes Mal, wenn der Cache als Antwort auf a zurückkehrt `NoSuchEntry``GetCacheEntry`, gilt dieser Abzweigschlüssel als * in Betrieb, * bis derselbe Schlüssel zusammen mit einem `PutCache` Eintrag geschrieben wird.

  Standardwert: 10 Sekunden
+ **Schlaf**: Definiert die Anzahl der Millisekunden, die ein Thread in den Ruhezustand versetzen soll, wenn der `fanOut` Wert überschritten wird.

  Standardwert: 20 Millisekunden

------
#### [ 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,
		},
	}
```

------

### Gemeinsam genutzter Cache
<a name="cache-shared"></a>

Standardmäßig erstellt der hierarchische Schlüsselbund jedes Mal, wenn Sie den Schlüsselbund instanziieren, einen neuen lokalen Cache. Der gemeinsame Cache kann jedoch dazu beitragen, Speicherplatz zu sparen, indem er es Ihnen ermöglicht, einen Cache über mehrere hierarchische Schlüsselringe hinweg gemeinsam zu nutzen. Anstatt für jeden hierarchischen Schlüsselbund, den Sie instanziieren, einen neuen Cache für kryptografische Materialien zu erstellen, speichert der gemeinsame Cache nur einen Cache im Speicher, der von allen hierarchischen Schlüsselbunden verwendet werden kann, die auf ihn verweisen. Der gemeinsame Cache trägt zur Optimierung der Speichernutzung bei, indem verhindert wird, dass kryptografisches Material über mehrere Schlüsselringe hinweg dupliziert wird. Stattdessen können die hierarchischen Schlüsselringe auf denselben zugrundeliegenden Cache zugreifen, wodurch der gesamte Speicherbedarf reduziert wird.

Wenn Sie Ihren gemeinsamen Cache erstellen, definieren Sie trotzdem den Cachetyp. Sie können einen [Standard-Cache](#cache-default) oder [StormTracking zwischenspeichern](#cache-stormtracking) als Cachetyp angeben oder einen beliebigen kompatiblen benutzerdefinierten Cache ersetzen. [MultiThreaded Cache](#cache-multithreaded)



**Partitionen**  
Mehrere hierarchische Schlüsselringe können einen einzigen gemeinsamen Cache verwenden. Wenn Sie einen hierarchischen Schlüsselbund mit einem gemeinsamen Cache erstellen, können Sie eine optionale Partitions-ID definieren. ** ** Die Partitions-ID unterscheidet, welcher hierarchische Schlüsselbund in den Cache schreibt. Wenn zwei hierarchische Schlüsselringe auf dieselbe Partitions-ID und Zweigschlüssel-ID verweisen[logical key store name](create-keystore.md#logical-key-store-name), teilen sich die beiden Schlüsselringe dieselben Cache-Einträge im Cache. Wenn Sie zwei hierarchische Schlüsselringe mit demselben gemeinsamen Cache, aber unterschiedlichen Partitions-IDs erstellen, greift jeder Schlüsselbund nur auf die Cache-Einträge von seiner eigenen angegebenen Partition innerhalb des gemeinsamen Caches zu. Die Partitionen fungieren als logische Unterteilungen innerhalb des gemeinsamen Caches, sodass jeder hierarchische Schlüsselbund unabhängig auf seiner eigenen zugewiesenen Partition arbeiten kann, ohne die in der anderen Partition gespeicherten Daten zu beeinträchtigen.

Wenn Sie beabsichtigen, die Cache-Einträge in einer Partition wiederzuverwenden oder gemeinsam zu nutzen, müssen Sie Ihre eigene Partitions-ID definieren. Wenn Sie die Partitions-ID an Ihren hierarchischen Schlüsselbund übergeben, kann der Schlüsselbund die Cache-Einträge, die bereits im gemeinsamen Cache vorhanden sind, wiederverwenden, sodass Sie das Zweigschlüsselmaterial nicht erneut abrufen und autorisieren müssen. Wenn Sie keine Partitions-ID angeben, wird dem Schlüsselbund jedes Mal, wenn Sie den hierarchischen Schlüsselbund instanziieren, automatisch eine eindeutige Partitions-ID zugewiesen.

Die folgenden Verfahren veranschaulichen, wie Sie einen gemeinsamen Cache mit dem [ Standard-Cachetyp erstellen ](#cache-default) und ihn an einen hierarchischen Schlüsselbund übergeben.

1. Erstellen Sie mithilfe der [ Material Providers Library `CryptographicMaterialsCache` (MPL) einen ](https://github.com/aws/aws-cryptographic-material-providers-library) (CMC).

------
#### [ 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)
   }
   ```

------

1. Erstellen Sie ein `CacheType` Objekt für den gemeinsamen Cache.

   Übergeben `sharedCryptographicMaterialsCache` Sie das in ** Schritt 1 erstellte Objekt ** an das neue `CacheType` Objekt.

------
#### [ 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}
   ```

------

1. Übergeben Sie das `sharedCache` Objekt aus ** Schritt 2 ** an Ihren hierarchischen Schlüsselbund.

   Wenn Sie einen hierarchischen Schlüsselbund mit einem gemeinsamen Cache erstellen, können Sie optional einen definieren, um Cache-Einträge über mehrere hierarchische Schlüsselringe hinweg gemeinsam `partitionID` zu nutzen. Wenn Sie keine Partitions-ID angeben, weist der hierarchische Schlüsselbund dem Schlüsselbund automatisch eine eindeutige Partitions-ID zu.
**Anmerkung**  
Ihre hierarchischen Schlüsselringe verwenden dieselben Cache-Einträge in einem gemeinsamen Cache, wenn Sie zwei oder mehr Schlüsselringe erstellen, die auf dieselbe Partitions-ID und Branch-Schlüssel-ID verweisen. [logical key store name](create-keystore.md#logical-key-store-name) Wenn Sie nicht möchten, dass sich mehrere Schlüsselringe dieselben Cacheeinträge teilen, müssen Sie für jeden hierarchischen Schlüsselbund eine eindeutige Partitions-ID verwenden.

   Im folgenden Beispiel wird ein hierarchischer Schlüsselbund mit einem[branch key ID supplier](#branch-key-id-supplier), und einem [ Cache-Limit von 600 Sekunden erstellt. ](#cache-limit) Weitere Informationen zu den Werten, die in der folgenden hierarchischen Schlüsselbundkonfiguration definiert sind, finden Sie unter. [Erstellen Sie einen hierarchischen Schlüsselbund](#initialize-hierarchical-keyring)

------
#### [ 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)
   }
   ```

------

## Erstellen Sie einen hierarchischen Schlüsselbund
<a name="initialize-hierarchical-keyring"></a>

Um einen hierarchischen Schlüsselbund zu erstellen, müssen Sie die folgenden Werte angeben:
+ **Ein Schlüsselspeicher **

  Der Schlüsselspeicher, der Ihre Filialschlüssel verwaltet und schützt. Sie müssen Ihren Schlüsselspeicher erstellen und konfigurieren, bevor Sie den hierarchischen Schlüsselbund erstellen. Weitere Informationen finden Sie unter [Wichtige Geschäfte in der AWS Encryption SDK](keystores.md).
+ 

  **Ein Cache-Limit für die Gültigkeitsdauer (TTL) **

  Die Zeitspanne in Sekunden, für die ein Eintrag für Branch-Key-Materials im lokalen Cache verwendet werden kann, bevor er abläuft. Das Cache-Limit TTL bestimmt, wie oft der Client anruft, AWS KMS um die Verwendung der Branch-Schlüssel zu autorisieren. Dieser Wert muss größer als null sein. Wenn das Cache-Limit TTL abgelaufen ist, wird der Eintrag nie mehr bedient und wird aus dem lokalen Cache entfernt.
+ **Eine Zweigschlüssel-ID **

  Sie können entweder den statisch konfigurieren`branch-key-id`, der einen einzelnen aktiven Filialschlüssel in Ihrem Schlüsselspeicher identifiziert, oder einen Anbieter für die Filialschlüssel-ID angeben.

  

  Der Anbieter der * Filialschlüssel-ID * verwendet die im Verschlüsselungskontext gespeicherten Felder, um zu ermitteln, welcher Filialschlüssel zum Entschlüsseln eines Datensatzes erforderlich ist.

  Wir empfehlen dringend, für Datenbanken mit mehreren Mandanten, bei denen jeder Mandant seinen eigenen Zweigschlüssel hat, einen Anbieter für Filialschlüssel-ID zu verwenden. Sie können den Anbieter der Filialschlüssel-ID verwenden, um einen benutzerfreundlichen Namen für Ihre Filialschlüssel-IDs zu erstellen, damit Sie die richtige Filialschlüssel-ID für einen bestimmten Mandanten leicht erkennen können. So können Sie beispielsweise mithilfe des Anzeigenamens auf einen Filialschlüssel verweisen, der `tenant1` anstelle von lautet`b3f61619-4d35-48ad-a275-050f87e15122`.

  Für Entschlüsselungsvorgänge können Sie entweder einen einzelnen hierarchischen Schlüsselbund statisch konfigurieren, um die Entschlüsselung auf einen einzelnen Mandanten zu beschränken, oder Sie können den Anbieter der Zweigschlüssel-ID verwenden, um zu ermitteln, welcher Mandant für die Entschlüsselung eines Datensatzes verantwortlich ist.
+ **(Optional) Ein Cache **

  Wenn Sie Ihren Cachetyp oder die Anzahl der Einträge für Branch Key Materials, die im lokalen Cache gespeichert werden können, anpassen möchten, geben Sie den Cachetyp und die Eintragskapazität an, wenn Sie den Schlüsselbund initialisieren.

  Der hierarchische Schlüsselbund unterstützt die folgenden Cachetypen: Standard, MultiThreaded, StormTracking und Shared. Weitere Informationen und Beispiele zur Definition der einzelnen Cachetypen finden Sie unter. [Wählen Sie einen Cache](#hierarchical-keyring-caches)

  Wenn Sie keinen Cache angeben, verwendet der hierarchische Schlüsselbund automatisch den Standard-Cachetyp und legt die Eintragskapazität auf 1000 fest.
+ **(Optional) Eine Partitions-ID **

  Wenn Sie die angeben[Gemeinsam genutzter Cache](#cache-shared), können Sie optional eine Partitions-ID definieren. Die Partitions-ID unterscheidet, welcher hierarchische Schlüsselbund in den Cache schreibt. Wenn Sie beabsichtigen, die Cache-Einträge in einer Partition wiederzuverwenden oder gemeinsam zu nutzen, müssen Sie Ihre eigene Partitions-ID definieren. Sie können eine beliebige Zeichenfolge für die Partitions-ID angeben. Wenn Sie keine Partitions-ID angeben, wird dem Schlüsselbund bei der Erstellung automatisch eine eindeutige Partitions-ID zugewiesen.

  Weitere Informationen finden Sie unter [Partitions](#shared-cache-partitions).
**Anmerkung**  
Ihre hierarchischen Schlüsselringe verwenden dieselben Cache-Einträge in einem gemeinsamen Cache, wenn Sie zwei oder mehr Schlüsselringe erstellen, die auf dieselbe Partitions-ID und Branch-Schlüssel-ID verweisen. [logical key store name](create-keystore.md#logical-key-store-name) Wenn Sie nicht möchten, dass sich mehrere Schlüsselringe dieselben Cacheeinträge teilen, müssen Sie für jeden hierarchischen Schlüsselbund eine eindeutige Partitions-ID verwenden.
+ **(Optional) Eine Liste von Grant-Tokens **

  Wenn Sie den Zugriff auf den KMS-Schlüssel in Ihrem hierarchischen Schlüsselbund mit [ Zuweisungen kontrollieren](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html), müssen Sie bei der Initialisierung des Schlüsselbundes alle erforderlichen Grant-Token angeben.

Die folgenden Beispiele zeigen, wie ein Schlüsselspeicher mit einer statischen Konfiguration konfiguriert wird. Wählen Sie Ihre bevorzugte Sprache:

------
#### [ Java ]

```
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.cryptography.keystore.KeyStore;
import software.amazon.cryptography.keystore.model.KeyStoreConfig;
import software.amazon.cryptography.keystore.model.KMSConfiguration;

final KeyStore keystore = KeyStore.builder()
        .KeyStoreConfig(KeyStoreConfig.builder()
                .ddbClient(DynamoDbClient.create())
                .ddbTableName({{keyStoreName}})
                .logicalKeyStoreName({{logicalKeyStoreName}})
                .kmsClient(KmsClient.create())
                .kmsConfiguration(KMSConfiguration.builder()
                        .kmsKeyArn({{kmsKeyArn}})
                        .build())
                .build())
        .build();
```

------
#### [ C\# / .NET ]

```
using Amazon.DynamoDBv2;
using Amazon.KeyManagementService;
using AWS.Cryptography.KeyStore;

var kmsConfig = new KMSConfiguration { KmsKeyArn = {{kmsKeyArn}} };
var keystoreConfig = new KeyStoreConfig
{
    KmsClient = new AmazonKeyManagementServiceClient(),
    KmsConfiguration = kmsConfig,
    DdbTableName = {{keyStoreName}},
    DdbClient = new AmazonDynamoDBClient(),
    LogicalKeyStoreName = {{logicalKeyStoreName}}
};
var keystore = new KeyStore(keystoreConfig);
```

------
#### [ Python ]

```
import boto3
from aws_cryptographic_material_providers.keystore import KeyStore
from aws_cryptographic_material_providers.keystore.config import KeyStoreConfig
from aws_cryptographic_material_providers.keystore.models import KMSConfigurationKmsKeyArn

ddb_client = boto3.client('dynamodb', region_name="us-west-2")
kms_client = boto3.client('kms', region_name="us-west-2")

keystore: KeyStore = KeyStore(
    config=KeyStoreConfig(
        ddb_client=ddb_client,
        ddb_table_name={{key_store_name}},
        logical_key_store_name={{logical_key_store_name}},
        kms_client=kms_client,
        kms_configuration=KMSConfigurationKmsKeyArn(
            value={{kms_key_id}}
        ),
    )
)
```

------
#### [ Rust ]

```
use aws_esdk::key_store::client as keystore_client;
use aws_esdk::key_store::types::key_store_config::KeyStoreConfig;
use aws_esdk::key_store::types::KmsConfiguration;

let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let key_store_config = KeyStoreConfig::builder()
    .kms_client(aws_sdk_kms::Client::new(&sdk_config))
    .ddb_client(aws_sdk_dynamodb::Client::new(&sdk_config))
    .ddb_table_name({{key_store_name}})
    .logical_key_store_name({{logical_key_store_name}})
    .kms_configuration(KmsConfiguration::KmsKeyArn({{kms_key_arn}}.to_string()))
    .build()?;

let keystore = keystore_client::Client::from_conf(key_store_config)?;
```

------
#### [ Go ]

```
import (
    "context"

    keystore "github.com/aws/aws-cryptographic-material-providers-library/mpl/awscryptographykeystoresmithygenerated"
    keystoretypes "github.com/aws/aws-cryptographic-material-providers-library/mpl/awscryptographykeystoresmithygeneratedtypes"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/aws/aws-sdk-go-v2/service/kms"
)

cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
    panic(err)
}
ddbClient := dynamodb.NewFromConfig(cfg)
kmsClient := kms.NewFromConfig(cfg)

kmsConfig := keystoretypes.KMSConfigurationMemberkmsKeyArn{
    Value: {{kmsKeyArn}},
}
keyStore, err := keystore.NewClient(keystoretypes.KeyStoreConfig{
    DdbTableName:        {{keyStoreTableName}},
    KmsConfiguration:    &kmsConfig,
    LogicalKeyStoreName: {{logicalKeyStoreName}},
    DdbClient:           ddbClient,
    KmsClient:           kmsClient,
})
if err != nil {
    panic(err)
}
```

------

Nachdem Sie Ihren Schlüsselspeicher konfiguriert haben, verwenden Sie das resultierende Schlüsselspeicherobjekt, um Ihren hierarchischen Schlüsselbund zu erstellen. In den folgenden Beispielen für hierarchische Schlüsselringe wird das von Ihnen konfigurierte Schlüsselspeicherobjekt verwendet.

### Erstellen Sie einen hierarchischen Schlüsselbund mit einer statischen Zweigschlüssel-ID
<a name="static-branch-key-id-config"></a>

Die folgenden Beispiele zeigen, wie Sie einen hierarchischen Schlüsselbund mit einer statischen Zweigschlüssel-ID, dem[Standard-Cache](#cache-default), und einem Cache-Limit (TTL) von 600 Sekunden erstellen.

------
#### [ Java ]

```
final MaterialProviders matProv = MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();
final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder()
        .keyStore(keystore)
        .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(keystore.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)
}
```

------

### Erstellen Sie einen hierarchischen Schlüsselbund mit einem Lieferanten für die Filialschlüssel-ID
<a name="branch-key-id-supplier-config"></a>

Die folgenden Verfahren veranschaulichen, wie Sie einen hierarchischen Schlüsselbund mit einem Lieferanten für die Filialschlüssel-ID erstellen.

1. Erstellen Sie einen Lieferanten mit einer Filialschlüssel-ID

   Das folgende Beispiel definiert einen Anbieter für die Zweigschlüssel-ID, der den Verschlüsselungskontext beim Verschlüsseln oder Entschlüsseln verwendet, um die Zweigschlüssel-ID für jeden Mandanten auszuwählen. Eine funktionierende Implementierung in jeder Sprache finden Sie unter:
   + Java: [ExampleBranchKeyIdSupplier.java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/examples/java/com/amazonaws/crypto/examples/keyrings/hierarchical/ExampleBranchKeyIdSupplier.java)
   + C\# /.NET: [ ExampleBranchKeySupplier.cs ](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/Keyring/AwsKmsHierarchical/ExampleBranchKeySupplier.cs)
   + Python: branch\_key\_id\_supplier\_example.py [https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/branch_key_id_supplier_example.py](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/branch_key_id_supplier_example.py)
   + Rust: [ example\_branch\_key\_id\_supplier.rs ](https://github.com/aws/aws-encryption-sdk/blob/mainline/releases/rust/esdk/examples/keyring/aws_kms_hierarchical/example_branch_key_id_supplier.rs)
   + Gehe zu: [ branchkeysupplier.go ](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/examples/keyring/awskmshierarchicalkeyring/branchkeysupplier.go)

------
#### [ 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. Erstellen Sie einen hierarchischen Schlüsselbund

   Die folgenden Beispiele initialisieren einen hierarchischen Schlüsselbund mit dem in ** Schritt 1 erstellten Anbieter für die Zweigschlüssel-ID**, einem TLL für den Cache von 600 Sekunden und einer maximalen Cachegröße von 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(keystore.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)
   }
   ```

------