

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.

# Datenschlüssel-Caching
<a name="data-key-caching"></a>

Das *Datenschlüssel-Caching* speichert [Datenschlüssel](concepts.md#DEK) und zugehörige[ kryptographische Materialien](data-caching-details.md#cache-entries) in einem Cache. Wenn Sie Daten ver- oder entschlüsseln, AWS Encryption SDK sucht der nach einem passenden Datenschlüssel im Cache. Wenn eine Übereinstimmung gefunden wird, wird der im Cache gespeicherte Datenschlüssel verwendet, statt einen neuen zu generieren. Das Datenschlüssel-Caching kann die Leistung verbessern, die Kosten senken und Ihnen helfen, innerhalb der Service-Limits zu bleiben, wenn Ihre Anwendung größer wird. 

Ihre Anwendung kann vom Datenschlüssel-Caching profitieren, wenn:
+ Sie Datenschlüssel wiederverwenden kann.
+ Sie zahlreiche Datenschlüssel generiert. 
+ Ihre kryptografischen Operationen unakzeptabel langsam, teuer, begrenzt oder ressourcen-intensiv sind.

Durch das Zwischenspeichern kann die Nutzung kryptografischer Dienste wie () reduziert werden. AWS Key Management Service AWS KMS Wenn Sie Ihr [AWS KMS requests-per-secondLimit](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second) erreichen, kann Caching helfen. Ihre Anwendung kann zwischengespeicherte Schlüssel verwenden, um einige Ihrer Datenschlüsselanforderungen zu bearbeiten, anstatt sie aufzurufen. AWS KMS(Sie können auch im [AWS Support Center](https://console.aws.amazon.com/support/home#/) einen Fall erstellen, um das Limit für Ihr Konto zu erhöhen.)

Das AWS Encryption SDK hilft Ihnen dabei, Ihren Datenschlüssel-Cache zu erstellen und zu verwalten. [Es bietet einen [lokalen Cache](data-caching-details.md#simplecache) und einen [Caching Cryptographic Materials Manager](data-caching-details.md#caching-cmm) (Caching CMM), der mit dem Cache interagiert und die von Ihnen festgelegten Sicherheitsschwellenwerte durchsetzt.](thresholds.md) Durch die Kombination dieser Komponenten profitieren Sie von der Effizienz der Wiederverwendung von Datenschlüsseln bei gleichzeitiger Wahrung der Sicherheit Ihres Systems.

Das Zwischenspeichern von Datenschlüsseln ist eine optionale Funktion von, die Sie mit Vorsicht verwenden sollten. AWS Encryption SDK Standardmäßig AWS Encryption SDK generiert der für jeden Verschlüsselungsvorgang einen neuen Datenschlüssel. Diese Technik unterstützt bewährte kryptografische Methoden gegen eine übermäßige Wiederverwendung von Datenschlüsseln. Im Allgemeinen sollten Sie das Datenschlüssel-Caching nur dann verwenden, wenn es erforderlich ist, um Ihre Leistungsziele zu erfüllen. Verwenden Sie dann die [Sicherheitsschwellenwerte](thresholds.md) für das Datenschlüssel-Caching, um sicherzustellen, dass Sie die minimale Menge an Caching verwenden, die zur Erreichung Ihrer Kosten- und Leistungsziele erforderlich ist. 

Version 3. *x* of the unterstützt AWS-Verschlüsselungs-SDK for Java nur das Caching-CMM mit der alten Master-Key-Provider-Schnittstelle, nicht die Keyring-Schnittstelle. Allerdings Version 4. *x* und höher von AWS Encryption SDK für .NET, Version 3. *x* der AWS-Verschlüsselungs-SDK for Java, Version 4. *x* der AWS-Verschlüsselungs-SDK for Python, Version 1. *x* von AWS Encryption SDK für Rust und Version 0.1. *x* oder höher von AWS Encryption SDK for Go unterstützen den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md), eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien. Mit dem hierarchischen Schlüsselbund verschlüsselte Inhalte können nur mit dem AWS KMS hierarchischen Schlüsselbund entschlüsselt werden. AWS KMS 

Eine ausführliche Erläuterung dieser Sicherheitsaspekte finden Sie im Sicherheits-Blog unter [AWS Encryption SDK: So entscheiden Sie, ob das Zwischenspeichern von Datenschlüsseln für Ihre Anwendung geeignet ist](https://aws.amazon.com/blogs/security/aws-encryption-sdk-how-to-decide-if-data-key-caching-is-right-for-your-application/). AWS 

**Topics**
+ [Das Datenschlüssel-Caching verwenden](implement-caching.md)
+ [Festlegen von Cache-Sicherheitsschwellenwerten](thresholds.md)
+ [Weitere Informationen zum Datenschlüssel-Caching](data-caching-details.md)
+ [Beispiel für das Datenschlüssel-Caching](sample-cache-example.md)

# Das Datenschlüssel-Caching verwenden
<a name="implement-caching"></a>

In diesem Thema erfahren Sie, wie Sie das Datenschlüssel-Caching in Ihrer Anwendung verwenden. Es führt Sie Schritt für Schritt durch den Vorgang. Anschließend kombiniert es die Schritte in einem einfachen Beispiel, das das Datenschüssel-Caching in einer Operation zum Verschlüsseln einer Zeichenfolge verwendet.

Die Beispiele in diesem Abschnitt zeigen, wie [Version 2.0 verwendet wird. ](about-versions.md)*x* und später von AWS Encryption SDK. Beispiele, die frühere Versionen verwenden, finden Sie in der [Release-Liste](https://github.com/aws/aws-encryption-sdk-c/releases) des GitHub Repositorys für Ihre [Programmiersprache](programming-languages.md) nach Ihrer Version.

Vollständige und getestete Beispiele für die Verwendung von Datenschlüssel-Caching in finden Sie AWS Encryption SDK unter:
+ C/C\$1\$1: [caching\$1cmm.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/caching_cmm.cpp)
+ [Java: SimpleDataKeyCachingExample .java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/examples/java/com/amazonaws/crypto/examples/v2/SimpleDataKeyCachingExample.java)
+ JavaScript [Browser: caching\$1cmm.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/caching_cmm.ts)
+ JavaScript Node.js: [caching\$1cmm.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-node/src/caching_cmm.ts)
+ Python: [data\$1key\$1caching\$1basic.py](https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/legacy/data_key_caching_basic.py)

[AWS Encryption SDK Für .NET wird das Zwischenspeichern von Datenschlüsseln](dot-net.md) nicht unterstützt.

**Topics**
+ [Verwenden der Zwischenspeicherung von Datenschlüsseln: Step-by-step](#implement-caching-steps)
+ [Beispiel für das Datenschlüssel-Caching: Verschlüsseln einer Zeichenfolge](#caching-example-encrypt-string)

## Verwenden der Zwischenspeicherung von Datenschlüsseln: Step-by-step
<a name="implement-caching-steps"></a>

Diese step-by-step Anweisungen zeigen Ihnen, wie Sie die Komponenten erstellen, die Sie für die Implementierung des Zwischenspeichers von Datenschlüsseln benötigen.
+ [Erstellen Sie einen Datenschlüssel-Cache](data-caching-details.md#simplecache). In diesen Beispielen verwenden wir den lokalen Cache, den der AWS Encryption SDK bereitstellt. Wir beschränken den Cache auf zehn Datenschlüssel.

   

------
#### [ C ]

  ```
  // Cache capacity (maximum number of entries) is required
  size_t cache_capacity = 10; 
  struct aws_allocator *allocator = aws_default_allocator();
  
  struct aws_cryptosdk_materials_cache *cache = aws_cryptosdk_materials_cache_local_new(allocator, cache_capacity);
  ```

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

  Das folgende Beispiel verwendet Version 2. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

  ```
  // Cache capacity (maximum number of entries) is required
  int MAX_CACHE_SIZE = 10; 
  
  CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(MAX_CACHE_SIZE);
  ```

------
#### [ JavaScript Browser ]

  ```
  const capacity = 10
  
  const cache = getLocalCryptographicMaterialsCache(capacity)
  ```

------
#### [ JavaScript Node.js ]

  ```
  const capacity = 10
  
  const cache = getLocalCryptographicMaterialsCache(capacity)
  ```

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

  ```
  # Cache capacity (maximum number of entries) is required
  MAX_CACHE_SIZE = 10
  
  cache = aws_encryption_sdk.LocalCryptoMaterialsCache(MAX_CACHE_SIZE)
  ```

------

   
+ Erstellen Sie einen [Hauptschlüsselanbieter](concepts.md#master-key-provider) (Java und Python) oder einen [Schlüsselbund](concepts.md#keyring) (C und JavaScript). In diesen Beispielen wird ein Hauptschlüsselanbieter AWS Key Management Service (AWS KMS) oder ein kompatibler [AWS KMS Schlüsselbund](use-kms-keyring.md) verwendet.

   

------
#### [ C ]

  ```
  // Create an AWS KMS keyring
  //   The input is the Amazon Resource Name (ARN) 
  //   of an AWS KMS key
  struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(kms_key_arn);
  ```

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

  Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

  ```
  // Create an AWS KMS master key provider
  //   The input is the Amazon Resource Name (ARN) 
  //   of an AWS KMS key
  MasterKeyProvider<KmsMasterKey> keyProvider = KmsMasterKeyProvider.builder().buildStrict(kmsKeyArn);
  ```

------
#### [ JavaScript Browser ]

  Im Browser müssen Sie Ihre Anmeldeinformationen sicher injizieren. In diesem Beispiel werden Anmeldeinformationen in einem Webpack (kms.webpack.config) definiert, mit dem Anmeldeinformationen zur Laufzeit aufgelöst werden. Es erstellt eine AWS KMS Client-Provider-Instanz aus einem AWS KMS Client und den Anmeldeinformationen. Wenn es dann den Schlüsselbund erstellt, übergibt es den Client-Provider zusammen mit dem () an den Konstruktor. AWS KMS key `generatorKeyId)`

  ```
  const { accessKeyId, secretAccessKey, sessionToken } = credentials
  
  const clientProvider = getClient(KMS, {
      credentials: {
        accessKeyId,
        secretAccessKey,
        sessionToken
      }
    })
  
  /*  Create an AWS KMS keyring
   *  You must configure the AWS KMS keyring with at least one AWS KMS key
  *  The input is the Amazon Resource Name (ARN) 
   */ of an AWS KMS key
  const keyring = new KmsKeyringBrowser({
      clientProvider,
      generatorKeyId,
      keyIds,
    })
  ```

------
#### [ JavaScript Node.js ]

  ```
  /* Create an AWS KMS keyring
   *   The input is the Amazon Resource Name (ARN) 
  */   of an AWS KMS key
  const keyring = new KmsKeyringNode({ generatorKeyId })
  ```

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

  ```
  # Create an AWS KMS master key provider
  #  The input is the Amazon Resource Name (ARN) 
  #  of an AWS KMS key
  key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[kms_key_arn])
  ```

------

   
+ [Erstellen Sie einen Manager für kryptografische Materialien zum Zwischenspeichern (Caching CMM](data-caching-details.md#caching-cmm)). 

   

  Ordnen Sie Ihr Caching-CMM Ihrem Cache und Ihrem Hauptschlüsselanbieter oder Schlüsselbund zu. [Legen Sie dann die Schwellenwerte für die Cache-Sicherheit](thresholds.md) auf dem Cache-CMM fest. 

   

------
#### [ C ]

  In der AWS-Verschlüsselungs-SDK for C können Sie ein Caching-CMM aus einem zugrunde liegenden CMM, z. B. dem Standard-CMM, oder aus einem Schlüsselbund erstellen. In diesem Beispiel wird der Caching-CMM aus einem Schlüsselbund erstellt.

  Nachdem Sie das Caching-CMM erstellt haben, können Sie Ihre Verweise auf den Schlüsselbund und den Cache freigeben. Details hierzu finden Sie unter [Referenzzählung](c-language-using.md#c-language-using-release).

  ```
  // Create the caching CMM
  //   Set the partition ID to NULL.
  //   Set the required maximum age value to 60 seconds.
  struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring(allocator, cache, kms_keyring, NULL, 60, AWS_TIMESTAMP_SECS);
  
  // Add an optional message threshold
  //   The cached data key will not be used for more than 10 messages.
  aws_status = aws_cryptosdk_caching_cmm_set_limit_messages(caching_cmm, 10);
  
  // Release your references to the cache and the keyring.
  aws_cryptosdk_materials_cache_release(cache);
  aws_cryptosdk_keyring_release(kms_keyring);
  ```

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

  Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the unterstützt AWS-Verschlüsselungs-SDK for Java kein Zwischenspeichern von Datenschlüsseln, aber es unterstützt den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md), eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

  ```
  /*
   * Security thresholds
   *   Max entry age is required. 
   *   Max messages (and max bytes) per entry are optional
   */
  int MAX_ENTRY_AGE_SECONDS = 60;
  int MAX_ENTRY_MSGS = 10;
         
  //Create a caching CMM
  CryptoMaterialsManager cachingCmm =
      CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider)
                                   .withCache(cache)
                                   .withMaxAge(MAX_ENTRY_AGE_SECONDS, TimeUnit.SECONDS)
                                   .withMessageUseLimit(MAX_ENTRY_MSGS)
                                   .build();
  ```

------
#### [ JavaScript Browser ]

  ```
  /*
   * Security thresholds
   *   Max age (in milliseconds) is required.
   *   Max messages (and max bytes) per entry are optional.
   */
  const maxAge = 1000 * 60
  const maxMessagesEncrypted = 10
  
  /* Create a caching CMM from a keyring  */
  const cachingCmm = new WebCryptoCachingMaterialsManager({
    backingMaterials: keyring,
    cache,
    maxAge,
    maxMessagesEncrypted
  })
  ```

------
#### [ JavaScript Node.js ]

  ```
  /*
   * Security thresholds
   *   Max age (in milliseconds) is required.
   *   Max messages (and max bytes) per entry are optional.
   */
  const maxAge = 1000 * 60
  const maxMessagesEncrypted = 10
  
  /* Create a caching CMM from a keyring  */
  const cachingCmm = new NodeCachingMaterialsManager({
    backingMaterials: keyring,
    cache,
    maxAge,
    maxMessagesEncrypted
  })
  ```

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

  ```
  # Security thresholds
  #   Max entry age is required. 
  #   Max messages (and max bytes) per entry are optional
  #
  MAX_ENTRY_AGE_SECONDS = 60.0
  MAX_ENTRY_MESSAGES = 10
         
  # Create a caching CMM
  caching_cmm = CachingCryptoMaterialsManager(
      master_key_provider=key_provider,
      cache=cache,
      max_age=MAX_ENTRY_AGE_SECONDS,
      max_messages_encrypted=MAX_ENTRY_MESSAGES
  )
  ```

------

Das ist alles. Lassen Sie sie dann den Cache für Sie AWS Encryption SDK verwalten oder fügen Sie Ihre eigene Cache-Verwaltungslogik hinzu.

Wenn Sie das Zwischenspeichern von Datenschlüsseln in einem Aufruf zum Verschlüsseln oder Entschlüsseln von Daten verwenden möchten, geben Sie Ihr Caching-CMM anstelle eines Hauptschlüsselanbieters oder eines anderen CMM an.

**Anmerkung**  
Wenn Sie Datenströme oder Daten unbekannter Größe verschlüsseln, stellen Sie sicher, dass Sie die Datengröße in der Anfrage angeben. Beim AWS Encryption SDK Verschlüsseln von Daten unbekannter Größe wird kein Datenschlüssel-Caching verwendet.

------
#### [ C ]

In der AWS-Verschlüsselungs-SDK for C erstellen Sie eine Sitzung mit dem Caching-CMM und verarbeiten dann die Sitzung. 

Standardmäßig werden Datenschlüssel AWS Encryption SDK nicht zwischengespeichert, wenn die Nachrichtengröße unbekannt und unbegrenzt ist. Um eine Zwischenspeicherung zuzulassen, wenn Sie die genaue Datengröße nicht kennen, verwenden Sie die `aws_cryptosdk_session_set_message_bound`-Methode, um eine maximale Größe für die Nachricht festzulegen. Legen Sie die Grenze größer als die geschätzte Nachrichtengröße fest. Wenn die tatsächliche Nachrichtengröße die Grenze überschreitet, schlägt die Verschlüsselungsoperation fehl.

```
/* Create a session with the caching CMM. Set the session mode to encrypt. */
struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm);

/* Set a message bound of 1000 bytes */
aws_status = aws_cryptosdk_session_set_message_bound(session, 1000);

/* Encrypt the message using the session with the caching CMM */
aws_status = aws_cryptosdk_session_process(
             session, output_buffer, output_capacity, &output_produced, input_buffer, input_len, &input_consumed);

/* Release your references to the caching CMM and the session. */
aws_cryptosdk_cmm_release(caching_cmm);
aws_cryptosdk_session_destroy(session);
```

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

Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

```
// When the call to encryptData specifies a caching CMM,
// the encryption operation uses the data key cache
final AwsCrypto encryptionSdk = AwsCrypto.standard();
return encryptionSdk.encryptData(cachingCmm, plaintext_source).getResult();
```

------
#### [ JavaScript Browser ]

```
const { result } = await encrypt(cachingCmm, plaintext)
```

------
#### [ JavaScript Node.js ]

Wenn Sie das CMM für die Zwischenspeicherung in der Datei AWS-Verschlüsselungs-SDK for JavaScript für Node.js verwenden, benötigt die `encrypt` Methode die Länge des Klartextes. Wenn Sie sie nicht angeben, wird der Datenschlüssel nicht zwischengespeichert. Wenn Sie eine Länge angeben, aber die von Ihnen bereitgestellten Klartextdaten diese Länge überschreiten, schlägt die Verschlüsselungsoperation fehl. Wenn Sie die genaue Länge des Klartextes nicht kennen, z. B. beim Streamen von Daten, geben Sie den größten erwarteten Wert an.

```
const { result } = await encrypt(cachingCmm, plaintext, { plaintextLength: plaintext.length })
```

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

```
# Set up an encryption client
client = aws_encryption_sdk.EncryptionSDKClient()

# When the call to encrypt specifies a caching CMM,
# the encryption operation uses the data key cache
#
encrypted_message, header = client.encrypt(
    source=plaintext_source,
    materials_manager=caching_cmm
)
```

------

## Beispiel für das Datenschlüssel-Caching: Verschlüsseln einer Zeichenfolge
<a name="caching-example-encrypt-string"></a>

Dieses einfache Codebeispiel verwendet das Datenschlüssel-Caching beim Verschlüsseln einer Zeichenfolge. Sie kombiniert den Code aus der [step-by-step Prozedur](#implement-caching-steps) zu Testcode, den Sie ausführen können.

Das Beispiel erstellt einen [lokalen Cache](data-caching-details.md#simplecache) und einen [Hauptschlüsselanbieter](concepts.md#master-key-provider) oder [Schlüsselbund](concepts.md#keyring) für einen AWS KMS key. [Anschließend werden der lokale Cache und der Hauptschlüsselanbieter oder der Schlüsselbund verwendet, um ein Caching-CMM mit entsprechenden Sicherheitsschwellenwerten zu erstellen.](thresholds.md) [In Java und Python spezifiziert die Verschlüsselungsanforderung das Caching-CMM, die zu verschlüsselnden Klartextdaten und einen Verschlüsselungskontext.](data-caching-details.md#caching-encryption-context) In C wird der Caching-CMM in der Sitzung angegeben und die Sitzung wird für die Verschlüsselungsanfrage bereitgestellt.

Um diese Beispiele auszuführen, müssen Sie den [Amazon-Ressourcennamen (ARN) eines angeben AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html). Stellen Sie sicher, dass Sie die [Berechtigung für die Verwendung des AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-users) zum Generieren eines Datenschlüssels besitzen.

Ausführlichere Beispiele aus der Praxis für die Erstellung und Verwendung eines Datenschlüssel-Caches finden Sie unter[Beispielcode für das Zwischenspeichern von Datenschlüsseln](sample-cache-example-code.md).

------
#### [ C ]

```
/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use
 * this file except in compliance with the License. A copy of the License is
 * located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <aws/cryptosdk/cache.h>
#include <aws/cryptosdk/cpp/kms_keyring.h>
#include <aws/cryptosdk/session.h>

void encrypt_with_caching(
    uint8_t *ciphertext,     // output will go here (assumes ciphertext_capacity bytes already allocated)
    size_t *ciphertext_len,  // length of output will go here
    size_t ciphertext_capacity,
    const char *kms_key_arn,
    int max_entry_age,
    int cache_capacity) {
    const uint64_t MAX_ENTRY_MSGS = 100;

    struct aws_allocator *allocator = aws_default_allocator();
    
    // Load error strings for debugging
    aws_cryptosdk_load_error_strings();

    // Create a keyring
    struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(kms_key_arn);

    // Create a cache
    struct aws_cryptosdk_materials_cache *cache = aws_cryptosdk_materials_cache_local_new(allocator, cache_capacity);

    // Create a caching CMM
    struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring(
        allocator, cache, kms_keyring, NULL, max_entry_age, AWS_TIMESTAMP_SECS);
    if (!caching_cmm) abort();

    if (aws_cryptosdk_caching_cmm_set_limit_messages(caching_cmm, MAX_ENTRY_MSGS)) abort();

    // Create a session
    struct aws_cryptosdk_session *session =        
        aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm);
    if (!session) abort();

    // Encryption context
    struct aws_hash_table *enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr_mut(session);
    if (!enc_ctx) abort();
    AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key, "purpose");
    AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value, "test");
    if (aws_hash_table_put(enc_ctx, enc_ctx_key, (void *)enc_ctx_value, NULL)) abort();

    // Plaintext data to be encrypted
    const char *my_data = "My plaintext data";
    size_t my_data_len  = strlen(my_data);
    if (aws_cryptosdk_session_set_message_size(session, my_data_len)) abort();

    // When the session uses a caching CMM, the encryption operation uses the data key cache
    // specified in the caching CMM.
    size_t bytes_read;
    if (aws_cryptosdk_session_process(
            session,
            ciphertext,
            ciphertext_capacity,
            ciphertext_len,
            (const uint8_t *)my_data,
            my_data_len,
            &bytes_read))
        abort();
    if (!aws_cryptosdk_session_is_done(session) || bytes_read != my_data_len) abort();

    aws_cryptosdk_session_destroy(session);
    aws_cryptosdk_cmm_release(caching_cmm);
    aws_cryptosdk_materials_cache_release(cache);
    aws_cryptosdk_keyring_release(kms_keyring);
}
```

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

Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package com.amazonaws.crypto.examples;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoMaterialsManager;
import com.amazonaws.encryptionsdk.MasterKeyProvider;
import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import com.amazonaws.encryptionsdk.caching.CryptoMaterialsCache;
import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache;
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * Encrypts a string using an &KMS; key and data key caching
 *
 * <p>
 * Arguments:
 * <ol>
 * <li>KMS Key ARN: To find the Amazon Resource Name of your &KMS; key,
 *     see 'Find the key ID and ARN' at https://docs.aws.amazon.com/kms/latest/developerguide/find-cmk-id-arn.html
 * <li>Max entry age: Maximum time (in seconds) that a cached entry can be used
 * <li>Cache capacity: Maximum number of entries in the cache
 * </ol>
 */
public class SimpleDataKeyCachingExample {

    /*
     * Security thresholds
     *   Max entry age is required.
     *   Max messages (and max bytes) per data key are optional
     */
    private static final int MAX_ENTRY_MSGS = 100;

    public static byte[] encryptWithCaching(String kmsKeyArn, int maxEntryAge, int cacheCapacity) {
        // Plaintext data to be encrypted
        byte[] myData = "My plaintext data".getBytes(StandardCharsets.UTF_8);

        // Encryption context
        // Most encrypted data should have an associated encryption context
        // 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("purpose", "test");

        // Create a master key provider
        MasterKeyProvider<KmsMasterKey> keyProvider = KmsMasterKeyProvider.builder()
            .buildStrict(kmsKeyArn);

        // Create a cache
        CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(cacheCapacity);

        // Create a caching CMM
        CryptoMaterialsManager cachingCmm =
            CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider)
                .withCache(cache)
                .withMaxAge(maxEntryAge, TimeUnit.SECONDS)
                .withMessageUseLimit(MAX_ENTRY_MSGS)
                .build();

        // When the call to encryptData specifies a caching CMM,
        // the encryption operation uses the data key cache
        final AwsCrypto encryptionSdk = AwsCrypto.standard();
        return encryptionSdk.encryptData(cachingCmm, myData, encryptionContext).getResult();
    }
}
```

------
#### [ JavaScript Browser ]

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

/* This is a simple example of using a caching CMM with a KMS keyring
 * to encrypt and decrypt using the AWS Encryption SDK for Javascript in a browser.
 */

import {
  KmsKeyringBrowser,
  KMS,
  getClient,
  buildClient,
  CommitmentPolicy,
  WebCryptoCachingMaterialsManager,
  getLocalCryptographicMaterialsCache,
} from '@aws-crypto/client-browser'
import { toBase64 } from '@aws-sdk/util-base64-browser'

/* This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
 * which enforces that this client only encrypts using committing algorithm suites
 * and enforces that this 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 `buildClient()`.
 */
const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)

/* This is injected by webpack.
 * The webpack.DefinePlugin or @aws-sdk/karma-credential-loader will replace the values when bundling.
 * The credential values are pulled from @aws-sdk/credential-provider-node
 * Use any method you like to get credentials into the browser.
 * See kms.webpack.config
 */
declare const credentials: {
  accessKeyId: string
  secretAccessKey: string
  sessionToken: string
}

/* This is done to facilitate testing. */
export async function testCachingCMMExample() {
  /* This example uses an &KMS; keyring. The generator key in a &KMS; keyring generates and encrypts the data key.
   * The caller needs kms:GenerateDataKey permission on the &KMS; key in generatorKeyId.
   */
  const generatorKeyId =
    'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt'

  /* Adding additional KMS keys that can decrypt.
   * The caller must have kms:Encrypt permission for every &KMS; key in keyIds.
   * You might list several keys in different AWS Regions.
   * This allows you to decrypt the data in any of the represented Regions.
   * In this example, the generator key
   * and the additional key are actually the same &KMS; key.
   * In `generatorId`, this &KMS; key is identified by its alias ARN.
   * In `keyIds`, this &KMS; key is identified by its key ARN.
   * In practice, you would specify different &KMS; keys,
   * or omit the `keyIds` parameter.
   * This is *only* to demonstrate how the &KMS; key ARNs are configured.
   */
  const keyIds = [
    'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f',
  ]

  /* Need a client provider that will inject correct credentials.
   * The credentials here are injected by webpack from your environment bundle is created
   * The credential values are pulled using @aws-sdk/credential-provider-node.
   * See kms.webpack.config
   * You should inject your credential into the browser in a secure manner
   * that works with your application.
   */
  const { accessKeyId, secretAccessKey, sessionToken } = credentials

  /* getClient takes a KMS client constructor
   * and optional configuration values.
   * The credentials can be injected here,
   * because browsers do not have a standard credential discovery process the way Node.js does.
   */
  const clientProvider = getClient(KMS, {
    credentials: {
      accessKeyId,
      secretAccessKey,
      sessionToken,
    },
  })

  /* You must configure the KMS keyring with your &KMS; keys */
  const keyring = new KmsKeyringBrowser({
    clientProvider,
    generatorKeyId,
    keyIds,
  })

  /* Create a cache to hold the data keys (and related cryptographic material).
   * This example uses the local cache provided by the Encryption SDK.
   * The `capacity` value represents the maximum number of entries
   * that the cache can hold.
   * To make room for an additional entry,
   * the cache evicts the oldest cached entry.
   * Both encrypt and decrypt requests count independently towards this threshold.
   * Entries that exceed any cache threshold are actively removed from the cache.
   * By default, the SDK checks one item in the cache every 60 seconds (60,000 milliseconds).
   * To change this frequency, pass in a `proactiveFrequency` value
   * as the second parameter. This value is in milliseconds.
   */
  const capacity = 100
  const cache = getLocalCryptographicMaterialsCache(capacity)

  /* The partition name lets multiple caching CMMs share the same local cryptographic cache.
   * By default, the entries for each CMM are cached separately. However, if you want these CMMs to share the cache,
   * use the same partition name for both caching CMMs.
   * If you don't supply a partition name, the Encryption SDK generates a random name for each caching CMM.
   * As a result, sharing elements in the cache MUST be an intentional operation.
   */
  const partition = 'local partition name'

  /* maxAge is the time in milliseconds that an entry will be cached.
   * Elements are actively removed from the cache.
   */
  const maxAge = 1000 * 60

  /* The maximum number of bytes that will be encrypted under a single data key.
   * This value is optional,
   * but you should configure the lowest practical value.
   */
  const maxBytesEncrypted = 100

  /* The maximum number of messages that will be encrypted under a single data key.
   * This value is optional,
   * but you should configure the lowest practical value.
   */
  const maxMessagesEncrypted = 10

  const cachingCMM = new WebCryptoCachingMaterialsManager({
    backingMaterials: keyring,
    cache,
    partition,
    maxAge,
    maxBytesEncrypted,
    maxMessagesEncrypted,
  })

  /* Encryption context is a *very* powerful tool for controlling
   * and managing access.
   * When you pass an encryption context to the encrypt function,
   * the encryption context is cryptographically bound to the ciphertext.
   * If you don't pass in the same encryption context when decrypting,
   * the decrypt function fails.
   * The encryption context is ***not*** secret!
   * Encrypted data is opaque.
   * You can use an encryption context to assert things about the encrypted data.
   * The encryption context helps you to determine
   * whether the ciphertext you retrieved is the ciphertext you expect to decrypt.
   * For example, if you are are only expecting data from 'us-west-2',
   * the appearance of a different AWS Region in the encryption context can indicate malicious interference.
   * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
   *
   * Also, cached data keys are reused ***only*** when the encryption contexts passed into the functions are an exact case-sensitive match.
   * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/data-caching-details.html#caching-encryption-context
   */
  const encryptionContext = {
    stage: 'demo',
    purpose: 'simple demonstration app',
    origin: 'us-west-2',
  }

  /* Find data to encrypt. */
  const plainText = new Uint8Array([1, 2, 3, 4, 5])

  /* Encrypt the data.
   * The caching CMM only reuses data keys
   * when it know the length (or an estimate) of the plaintext.
   * However, in the browser,
   * you must provide all of the plaintext to the encrypt function.
   * Therefore, the encrypt function in the browser knows the length of the plaintext
   * and does not accept a plaintextLength option.
   */
  const { result } = await encrypt(cachingCMM, plainText, { encryptionContext })

  /* Log the plain text
   * only for testing and to show that it works.
   */
  console.log('plainText:', plainText)
  document.write('</br>plainText:' + plainText + '</br>')

  /* Log the base64-encoded result
   * so that you can try decrypting it with another AWS Encryption SDK implementation.
   */
  const resultBase64 = toBase64(result)
  console.log(resultBase64)
  document.write(resultBase64)

  /* Decrypt the data.
   * NOTE: This decrypt request will not use the data key
   * that was cached during the encrypt operation.
   * Data keys for encrypt and decrypt operations are cached separately.
   */
  const { plaintext, messageHeader } = await decrypt(cachingCMM, result)

  /* Grab the encryption context so you can verify it. */
  const { encryptionContext: decryptedContext } = messageHeader

  /* Verify the encryption context.
   * If you use an algorithm suite with signing,
   * the Encryption SDK adds a name-value pair to the encryption context that contains the public key.
   * Because the encryption context might contain additional key-value pairs,
   * do not include a test that requires that all key-value pairs match.
   * Instead, verify that the key-value pairs that you supplied to the `encrypt` function are included in the encryption context that the `decrypt` function returns.
   */
  Object.entries(encryptionContext).forEach(([key, value]) => {
    if (decryptedContext[key] !== value)
      throw new Error('Encryption Context does not match expected values')
  })

  /* Log the clear message
   * only for testing and to show that it works.
   */
  document.write('</br>Decrypted:' + plaintext)
  console.log(plaintext)

  /* Return the values to make testing easy. */
  return { plainText, plaintext }
}
```

------
#### [ JavaScript Node.js ]

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {
  KmsKeyringNode,
  buildClient,
  CommitmentPolicy,
  NodeCachingMaterialsManager,
  getLocalCryptographicMaterialsCache,
} from '@aws-crypto/client-node'

/* This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
 * which enforces that this client only encrypts using committing algorithm suites
 * and enforces that this 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 `buildClient()`.
 */
const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)

export async function cachingCMMNodeSimpleTest() {
  /* An &KMS; key is required to generate the data key.
   * You need kms:GenerateDataKey permission on the &KMS; key in generatorKeyId.
   */
  const generatorKeyId =
    'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt'

  /* Adding alternate &KMS; keys that can decrypt.
   * Access to kms:Encrypt is required for every &KMS; key in keyIds.
   * You might list several keys in different AWS Regions.
   * This allows you to decrypt the data in any of the represented Regions.
   * In this example, the generator key
   * and the additional key are actually the same &KMS; key.
   * In `generatorId`, this &KMS; key is identified by its alias ARN.
   * In `keyIds`, this &KMS; key is identified by its key ARN.
   * In practice, you would specify different &KMS; keys,
   * or omit the `keyIds` parameter.
   * This is *only* to demonstrate how the &KMS; key ARNs are configured.
   */
  const keyIds = [
    'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f',
  ]

  /* The &KMS; keyring must be configured with the desired &KMS; keys
   * This example passes the keyring to the caching CMM
   * instead of using it directly.
   */
  const keyring = new KmsKeyringNode({ generatorKeyId, keyIds })

  /* Create a cache to hold the data keys (and related cryptographic material).
   * This example uses the local cache provided by the Encryption SDK.
   * The `capacity` value represents the maximum number of entries
   * that the cache can hold.
   * To make room for an additional entry,
   * the cache evicts the oldest cached entry.
   * Both encrypt and decrypt requests count independently towards this threshold.
   * Entries that exceed any cache threshold are actively removed from the cache.
   * By default, the SDK checks one item in the cache every 60 seconds (60,000 milliseconds).
   * To change this frequency, pass in a `proactiveFrequency` value
   * as the second parameter. This value is in milliseconds.
   */
  const capacity = 100
  const cache = getLocalCryptographicMaterialsCache(capacity)

  /* The partition name lets multiple caching CMMs share the same local cryptographic cache.
   * By default, the entries for each CMM are cached separately. However, if you want these CMMs to share the cache,
   * use the same partition name for both caching CMMs.
   * If you don't supply a partition name, the Encryption SDK generates a random name for each caching CMM.
   * As a result, sharing elements in the cache MUST be an intentional operation.
   */
  const partition = 'local partition name'

  /* maxAge is the time in milliseconds that an entry will be cached.
   * Elements are actively removed from the cache.
   */
  const maxAge = 1000 * 60

  /* The maximum amount of bytes that will be encrypted under a single data key.
   * This value is optional,
   * but you should configure the lowest value possible.
   */
  const maxBytesEncrypted = 100

  /* The maximum number of messages that will be encrypted under a single data key.
   * This value is optional,
   * but you should configure the lowest value possible.
   */
  const maxMessagesEncrypted = 10

  const cachingCMM = new NodeCachingMaterialsManager({
    backingMaterials: keyring,
    cache,
    partition,
    maxAge,
    maxBytesEncrypted,
    maxMessagesEncrypted,
  })

  /* Encryption context is a *very* powerful tool for controlling
   * and managing access.
   * When you pass an encryption context to the encrypt function,
   * the encryption context is cryptographically bound to the ciphertext.
   * If you don't pass in the same encryption context when decrypting,
   * the decrypt function fails.
   * The encryption context is ***not*** secret!
   * Encrypted data is opaque.
   * You can use an encryption context to assert things about the encrypted data.
   * The encryption context helps you to determine
   * whether the ciphertext you retrieved is the ciphertext you expect to decrypt.
   * For example, if you are are only expecting data from 'us-west-2',
   * the appearance of a different AWS Region in the encryption context can indicate malicious interference.
   * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
   *
   * Also, cached data keys are reused ***only*** when the encryption contexts passed into the functions are an exact case-sensitive match.
   * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/data-caching-details.html#caching-encryption-context
   */
  const encryptionContext = {
    stage: 'demo',
    purpose: 'simple demonstration app',
    origin: 'us-west-2',
  }

  /* Find data to encrypt.  A simple string. */
  const cleartext = 'asdf'

  /* Encrypt the data.
   * The caching CMM only reuses data keys
   * when it know the length (or an estimate) of the plaintext.
   * If you do not know the length,
   * because the data is a stream
   * provide an estimate of the largest expected value.
   *
   * If your estimate is smaller than the actual plaintext length
   * the AWS Encryption SDK will throw an exception.
   *
   * If the plaintext is not a stream,
   * the AWS Encryption SDK uses the actual plaintext length
   * instead of any length you provide.
   */
  const { result } = await encrypt(cachingCMM, cleartext, {
    encryptionContext,
    plaintextLength: 4,
  })

  /* Decrypt the data.
   * NOTE: This decrypt request will not use the data key
   * that was cached during the encrypt operation.
   * Data keys for encrypt and decrypt operations are cached separately.
   */
  const { plaintext, messageHeader } = await decrypt(cachingCMM, result)

  /* Grab the encryption context so you can verify it. */
  const { encryptionContext: decryptedContext } = messageHeader

  /* Verify the encryption context.
   * If you use an algorithm suite with signing,
   * the Encryption SDK adds a name-value pair to the encryption context that contains the public key.
   * Because the encryption context might contain additional key-value pairs,
   * do not include a test that requires that all key-value pairs match.
   * Instead, verify that the key-value pairs that you supplied to the `encrypt` function are included in the encryption context that the `decrypt` function returns.
   */
  Object.entries(encryptionContext).forEach(([key, value]) => {
    if (decryptedContext[key] !== value)
      throw new Error('Encryption Context does not match expected values')
  })

  /* Return the values so the code can be tested. */
  return { plaintext, result, cleartext, messageHeader }
}
```

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

```
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Example of encryption with data key caching."""
import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy


def encrypt_with_caching(kms_key_arn, max_age_in_cache, cache_capacity):
    """Encrypts a string using an &KMS; key and data key caching.

    :param str kms_key_arn: Amazon Resource Name (ARN) of the &KMS; key
    :param float max_age_in_cache: Maximum time in seconds that a cached entry can be used
    :param int cache_capacity: Maximum number of entries to retain in cache at once
    """
    # Data to be encrypted
    my_data = "My plaintext data"

    # Security thresholds
    #   Max messages (or max bytes per) data key are optional
    MAX_ENTRY_MESSAGES = 100

    # Create an encryption context
    encryption_context = {"purpose": "test"}

    # Set up an encryption client with an explicit commitment policy. Note that if you do not explicitly choose a
    # commitment policy, REQUIRE_ENCRYPT_REQUIRE_DECRYPT is used by default.
    client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)

    # Create a master key provider for the &KMS; key
    key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[kms_key_arn])

    # Create a local cache
    cache = aws_encryption_sdk.LocalCryptoMaterialsCache(cache_capacity)

    # Create a caching CMM
    caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager(
        master_key_provider=key_provider,
        cache=cache,
        max_age=max_age_in_cache,
        max_messages_encrypted=MAX_ENTRY_MESSAGES,
    )

    # When the call to encrypt data specifies a caching CMM,
    # the encryption operation uses the data key cache specified
    # in the caching CMM
    encrypted_message, _header = client.encrypt(
        source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context
    )

    return encrypted_message
```

------

# Festlegen von Cache-Sicherheitsschwellenwerten
<a name="thresholds"></a>

Wenn Sie das Zwischenspeichern von Datenschlüsseln implementieren, müssen Sie die Sicherheitsschwellenwerte konfigurieren, die das [Caching-CMM durchsetzt](data-caching-details.md#caching-cmm). 

Die Sicherheitsschwellenwerte helfen Ihnen, die Verwendungsdauer jedes im Cache gespeicherten Datenschlüssels und die Menge der unter jedem Datenschlüssel geschützten Daten zu begrenzen. Das Caching-CMM gibt zwischengespeicherte Datenschlüssel nur zurück, wenn der Cacheeintrag allen Sicherheitsschwellenwerten entspricht. Wenn der Cache-Eintrag einen vorgegebenen Schwellenwert überschreitet, wird der Eintrag für die aktuelle Operation nicht verwendet und so bald wie möglich aus dem Cache entfernt. Die erste Verwendung der einzelnen Datenschlüssel (vor dem Caching) ist davon ausgenommen. 

Verwenden Sie als Regel die minimale Menge an Caching, die erforderlich ist, um Ihre Kosten- und Leistungsziele zu erreichen. 

[Es speichert AWS Encryption SDK nur Datenschlüssel im Cache, die mithilfe einer Schlüsselableitungsfunktion verschlüsselt wurden.](https://en.wikipedia.org/wiki/Key_derivation_function) Außerdem richtet es Obergrenzen für einige Schwellenwerte ein. Diese Einschränkungen stellen sicher, dass Datenschlüssel nicht über ihre kryptografischen Obergrenzen hinaus wiederverwendet werden. Da Ihre Klartext-Datenschlüssel jedoch im Cache gespeichert werden (standardmäßig im Arbeitsspeicher), sollten Sie versuchen, die Zeit zu minimieren, wie lange die Schlüssel gespeichert werden. Versuchen Sie auch, die Datenmenge zu begrenzen, die offengelegt werden könnte, wenn ein Schlüssel verletzt wird.

Beispiele für die Festlegung von Cache-Sicherheitsschwellenwerten finden Sie unter [AWS Encryption SDK: So entscheiden Sie, ob das Zwischenspeichern von Datenschlüsseln für Ihre Anwendung geeignet ist](https://aws.amazon.com/blogs/security/aws-encryption-sdk-how-to-decide-if-data-key-caching-is-right-for-your-application/) im Sicherheits-Blog. AWS 

**Anmerkung**  
Der Caching-CMM erzwingt alle folgenden Schwellenwerte. Wenn Sie keinen optionalen Wert angeben, verwendet der Caching-CMM den Standardwert.  
Um das Zwischenspeichern von Datenschlüsseln vorübergehend zu deaktivieren, AWS Encryption SDK bieten die Java- und Python-Implementierungen von einen *Null-Cache für kryptografische Materialien (Null-Cache*). Der Null-Cache gibt einen Fehler für alle `GET`-Anfragen zurück und reagiert nicht auf `PUT`-Anfragen. Wir empfehlen Ihnen die Verwendung des Null-Cache, anstatt die [Cache-Kapazität](data-caching-details.md#simplecache) oder den Sicherheitsschwellenwert auf 0 zu setzen. Weitere Informationen finden Sie im Null-Cache in [Java](https://aws.github.io/aws-encryption-sdk-java/com/amazonaws/encryptionsdk/caching/NullCryptoMaterialsCache.html) und [Python](https://aws-encryption-sdk-python.readthedocs.io/en/latest/generated/aws_encryption_sdk.caches.null.html).

**Höchstalter (erforderlich)**  
Legt fest, wie lange ein im Cache gespeicherter Eintrag verwendet werden kann, beginnend ab dem Zeitpunkt, zu dem er hinzugefügt wurde. Dieser Wert ist erforderlich. Geben Sie einen Wert größer als 0 ein. Der maximale Alterswert wird dadurch AWS Encryption SDK nicht begrenzt.  
Alle Sprachimplementierungen von AWS Encryption SDK definieren das maximale Alter in Sekunden, mit Ausnahme von AWS-Verschlüsselungs-SDK for JavaScript, das Millisekunden verwendet.  
Verwenden Sie das kürzeste Intervall, bei dem Ihre Anwendung noch vom Cache profitieren kann. Sie können die maximale Altersgrenze wie eine Schlüsselrotationsrichtlinie verwenden. Verwenden Sie sie, um die Wiederverwendung von Datenschlüsseln einzuschränken, die Offenlegung von kryptographischem Material zu minimieren und Datenschlüssel zu entfernen, deren Richtlinien sich möglicherweise geändert haben, während sie im Cache gespeichert waren.

**Maximale Anzahl verschlüsselter Nachrichten (optional)**  
Gibt die maximale Anzahl der Nachrichten an, die ein im Cache gespeicherter Datenschlüssel verschlüsseln kann. Dieser Wert ist optional. Geben Sie einen Wert zwischen 1 und 2^32 Nachrichten ein. Der Standardwert beträgt 2^32 Nachrichten  
Stellen Sie die Anzahl der durch jeden im Cache gespeicherten Schlüssel geschützten Nachrichten so ein, dass sie groß genug ist, um Nutzen aus der Wiederverwendung zu erhalten, aber klein genug, um die Anzahl der Nachrichten zu begrenzen, die bei einer Gefährdung eines Schlüssels offengelegt werden könnten.

**Maximale Anzahl verschlüsselter Bytes (optional)**  
Gibt die maximale Anzahl der Bytes an, die ein im Cache gespeicherter Datenschlüssel verschlüsseln kann. Dieser Wert ist optional. Geben Sie einen Wert zwischen 0 und 2^63 - 1 ein. Der Standardwert lautet 2^63 - 1. Bei einem Wert von 0 können Sie Datenschlüssel-Caching nur verwenden, wenn Sie leere Nachrichtenzeichenfolgen verschlüsseln.  
Die Bytes in der aktuellen Anfrage sind bei der Auswertung dieses Schwellenwerts enthalten. Wenn die verarbeiteten Bytes plus die aktuellen Bytes den Schwellenwert überschreiten, wird der im Cache gespeicherte Datenschlüssel aus dem Cache entfernt, auch wenn er bei einer kleineren Anfrage verwendet werden hätte können. 

# Weitere Informationen zum Datenschlüssel-Caching
<a name="data-caching-details"></a>

Für die meisten Anwendungen ist die Standard-Implementierung des Datenschlüssel-Cachings ausreichend, ohne dass benutzerdefinierter Code geschrieben werden muss. Dieser Abschnitt beschreibt die Standard-Implementierung und einige Details zu Optionen. 

**Topics**
+ [Wie das Datenschlüssel-Caching funktioniert](#how-caching-works)
+ [Erstellen eines Cache für kryptografische Materialien](#simplecache)
+ [Erstellen eines Managers von kryptographischen Materialien, der Caching verwendet](#caching-cmm)
+ [Was befinde sich in einem Datenschlüssel-Cache-Eintrag?](#cache-entries)
+ [Verschlüsselungskontext: Wie Cache-Einträge ausgewählt werden](#caching-encryption-context)
+ [Benutzt meine Anwendung zwischengespeicherte Datenschlüssel?](#caching-effect)

## Wie das Datenschlüssel-Caching funktioniert
<a name="how-caching-works"></a>

Wenn Sie Datenschlüssel-Caching in einer Anfrage verwenden, um Daten zu verschlüsseln oder zu entschlüsseln, sucht das AWS Encryption SDK zuerst im Cache nach einem Datenschlüssel, der der Anfrage entspricht. Wenn es eine gültige Übereinstimmung findet, verwendet es den zwischengespeicherten Datenschlüssel, um die Daten zu verschlüsseln. Andernfalls erzeugt es einen neuen Datenschlüssel, genau wie ohne den Cache. 

Das Datenschlüssel-Caching wird nicht für Daten unbekannter Größe verwendet, wie z. B. gestreamte Daten. Auf diese Weise kann das Caching-CMM den Schwellenwert für die [maximale Bytezahl](thresholds.md) ordnungsgemäß durchsetzen. Um dieses Verhalten zu vermeiden, fügen Sie der Verschlüsselungsanfrage die Nachrichtengröße hinzu. 

Beim Zwischenspeichern von Datenschlüsseln wird zusätzlich zu einem Cache ein [Caching-Manager für kryptografisches Material (Caching CMM](#caching-cmm)) verwendet. [[Der Caching-CMM ist ein spezialisierter [Cryptographic Materials Manager (CMM), der mit einem Cache und einem zugrunde liegenden CMM interagiert](concepts.md#crypt-materials-manager).](concepts.md#crypt-materials-manager)](#simplecache) (Wenn Sie einen [Hauptschlüsselanbieter oder einen Schlüsselbund](concepts.md#master-key-provider) angeben, AWS Encryption SDK erstellt dieser ein Standard-CMM für Sie.) Das zwischengespeicherte CMM speichert die Datenschlüssel, die das zugrunde liegende CMM zurückgibt. Das Cache-CMM setzt auch die von Ihnen festgelegten Cache-Sicherheitsschwellenwerte durch. 

Um zu verhindern, dass der falsche Datenschlüssel aus dem Cache ausgewählt wird, setzen alle kompatiblen Zwischenspeicherungen CMMs voraus, dass die folgenden Eigenschaften der zwischengespeicherten kryptografischen Materialien mit der Materialanforderung übereinstimmen.
+ [Algorithmen-Paket](concepts.md#crypto-algorithm)
+ [Verschlüsselungskontext](#caching-encryption-context) (auch, wenn dieser leer ist)
+ Partitionsname (eine Zeichenfolge, die das Caching-CMM identifiziert)
+ (Nur Entschlüsselung) Verschlüsselte Datenschlüssel

**Anmerkung**  
Die AWS Encryption SDK Zwischenspeicherung von Datenschlüsseln erfolgt nur dann, wenn die [Algorithmus-Suite](concepts.md#crypto-algorithm) eine Funktion zur [Schlüsselableitung](https://en.wikipedia.org/wiki/Key_derivation_function) verwendet.

Die folgenden Workflows zeigen, wie eine Anforderung zum Verschlüsseln von Daten mit und ohne Datenschlüssel-Caching verarbeitet wird. Sie zeigen, wie die von Ihnen erstellten Caching-Komponenten, einschließlich des Caches und des Caching-CMM, dabei verwendet werden.

### Verschlüsseln von Daten ohne Caching
<a name="workflow-wo-cache"></a>

So rufen Sie Verschlüsselungsmaterialien ohne Caching ab:

1. Eine Anwendung fordert sie auf, Daten AWS Encryption SDK zu verschlüsseln. 

   Die Anfrage spezifiziert einen Hauptschlüsselanbieter oder einen Schlüsselbund. Das AWS Encryption SDK erstellt ein Standard-CMM, das mit Ihrem Hauptschlüsselanbieter oder Schlüsselbund interagiert.

1. Der AWS Encryption SDK fragt das CMM nach Verschlüsselungsmaterial (besorgen Sie sich kryptografisches Material).

1. Das CMM fragt seinen [Schlüsselbund](concepts.md#keyring) (C und JavaScript) oder seinen [Hauptschlüsselanbieter](concepts.md#master-key-provider) (Java und Python) nach kryptografischem Material. Dies kann einen Aufruf eines kryptografischen Dienstes wie () beinhalten. AWS Key Management Service AWS KMS Das CMM gibt die Verschlüsselungsmaterialien an den zurück. AWS Encryption SDK

1. Der AWS Encryption SDK verwendet den Klartext-Datenschlüssel, um die Daten zu verschlüsseln. Es speichert die verschlüsselten Daten und verschlüsselten Datenschlüssel in einer [verschlüsselten Nachricht](concepts.md#message), die an den Benutzer zurückgegeben wird.

![\[Verschlüsseln von Daten ohne Caching\]](http://docs.aws.amazon.com/de_de/encryption-sdk/latest/developer-guide/images/encrypt-workflow-no-cache.png)


### Verschlüsseln von Daten mit Caching
<a name="workflow-with-cache"></a>

So rufen Sie Verschlüsselungsmaterialien mit Datenschlüssel-Caching ab:

1. Eine Anwendung fordert sie auf, Daten AWS Encryption SDK zu verschlüsseln. 

   Die Anforderung spezifiziert einen [Caching Cryptographic Materials Manager (Caching CMM)](#caching-cmm), der einem zugrunde liegenden Cryptographic Materials Manager (CMM) zugeordnet ist. Wenn Sie einen Hauptschlüsselanbieter oder einen Schlüsselbund angeben, erstellt dieser ein Standard-CMM für Sie AWS Encryption SDK .

1. Das SDK fragt den angegebenen Caching-CMM nach Verschlüsselungsmaterialien.

1. Das Caching-CMM fordert Verschlüsselungsmaterial aus dem Cache an.

   1. Wenn der Cache eine Übereinstimmung findet, aktualisiert er das Alter und die Verwendungswerte des entsprechenden Cache-Eintrags und gibt die zwischengespeicherten Verschlüsselungsmaterialien an das zwischengespeicherte CMM zurück. 

      Wenn der Cache-Eintrag seinen [Sicherheitsschwellenwerten](thresholds.md) entspricht, gibt ihn das Cache-CMM an das SDK zurück. Andernfalls weist es den Cache an, den Eintrag zu entfernen, und geht so vor, als gäbe es keine Übereinstimmung.

   1. Wenn der Cache keine gültige Übereinstimmung findet, fordert das Cache-CMM das zugrunde liegende CMM auf, einen neuen Datenschlüssel zu generieren. 

      Das zugrunde liegende CMM bezieht die kryptografischen Materialien von seinem Schlüsselbund (C und JavaScript) oder seinem Hauptschlüsselanbieter (Java und Python). Dabei könnte es sich um einen Aufruf eines Dienstes handeln, z. B. AWS Key Management Service. Das zugrunde liegende CMM gibt die Klartext- und verschlüsselten Kopien des Datenschlüssels an das zwischengespeicherte CMM zurück. 

      Das Caching-CMM speichert die neuen Verschlüsselungsmaterialien im Cache.

1. Das zwischengespeicherte CMM gibt die Verschlüsselungsmaterialien an den zurück. AWS Encryption SDK

1. Der AWS Encryption SDK verwendet den Klartext-Datenschlüssel, um die Daten zu verschlüsseln. Es speichert die verschlüsselten Daten und verschlüsselten Datenschlüssel in einer [verschlüsselten Nachricht](concepts.md#message), die an den Benutzer zurückgegeben wird.

![\[Verschlüsseln von Daten mit Datenschlüssel-Caching\]](http://docs.aws.amazon.com/de_de/encryption-sdk/latest/developer-guide/images/encrypt-workflow-with-cache.png)


## Erstellen eines Cache für kryptografische Materialien
<a name="simplecache"></a>

Der AWS Encryption SDK definiert die Anforderungen an einen Cache für kryptografisches Material, der beim Zwischenspeichern von Datenschlüsseln verwendet wird. Er stellt auch einen lokalen Cache bereit, bei dem es sich um einen konfigurierbaren [LRU-Cache (In-Memory-Cache, Least Recently Used)](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_Recently_Used_.28LRU.29) handelt. Um eine Instanz des lokalen Caches zu erstellen, verwenden Sie den `LocalCryptoMaterialsCache` Konstruktor in Java und Python, die getLocalCryptographic MaterialsCache Funktion in JavaScript oder den `aws_cryptosdk_materials_cache_local_new` Konstruktor in C.

Der lokale Cache enthält Logik für die grundlegende Cacheverwaltung, einschließlich des Hinzufügens, Entfernens und Abgleichs zwischengespeicherter Einträge sowie der Verwaltung des Caches. Sie müssen keine benutzerdefinierte Cache-Verwaltungslogik schreiben. Sie können den lokalen Cache unverändert verwenden, ihn anpassen oder durch einen beliebigen kompatiblen Cache ersetzen. 

Wenn Sie einen lokalen Cache erstellen, legen Sie dessen *Kapazität* fest, d. h. die maximale Anzahl von Einträgen, die der Cache aufnehmen kann. Diese Einstellung hilft Ihnen, einen effizienten Cache mit begrenzter Wiederverwendung von Datenschlüsseln zu entwerfen.

Der AWS-Verschlüsselungs-SDK for Java und der stellt AWS-Verschlüsselungs-SDK for Python außerdem einen *Null-Cache für kryptografisches Material* bereit (NullCryptoMaterialsCache). Der NullCryptoMaterialsCache gibt für alle `GET` Operationen einen Fehlschlag zurück und reagiert nicht auf `PUT` Operationen. Sie können das während der NullCryptoMaterialsCache Testphase verwenden oder um das Caching in einer Anwendung, die Caching-Code enthält, vorübergehend zu deaktivieren. 

In der AWS Encryption SDK ist jeder Cache für kryptografisches Material einem [Caching-Manager für kryptografische Materialien (Caching CMM](#caching-cmm)) zugeordnet. [Das CMM für die Zwischenspeicherung ruft Datenschlüssel aus dem Cache ab, legt Datenschlüssel in den Cache und setzt die von Ihnen festgelegten Sicherheitsschwellenwerte durch.](thresholds.md) Wenn Sie ein Caching-CMM erstellen, geben Sie den Cache an, den es verwendet, und den zugrunde liegenden CMM oder Hauptschlüsselanbieter, der die zwischengespeicherten Datenschlüssel generiert.

## Erstellen eines Managers von kryptographischen Materialien, der Caching verwendet
<a name="caching-cmm"></a>

Um das Zwischenspeichern von Datenschlüsseln zu aktivieren, erstellen Sie einen [Cache und einen Caching-Manager](#simplecache) für *kryptografische Materialien (Caching-CMM*). [[Anschließend geben Sie in Ihren Anfragen zum Verschlüsseln oder Entschlüsseln von Daten statt eines standardmäßigen [Cryptographic Materials Manager (](concepts.md#crypt-materials-manager)CMM), eines Masterschlüsselanbieters oder eines Schlüsselbunds einen CMM für die Zwischenspeicherung an.](concepts.md#keyring)](concepts.md#master-key-provider)

Es gibt zwei Arten von. CMMs Beide rufen Datenschlüssel (und verwandtes kryptografisches Material) ab, aber auf unterschiedliche Weise, wie folgt:
+ Ein CMM ist mit einem Schlüsselbund (C oder JavaScript) oder einem Hauptschlüsselanbieter (Java und Python) verknüpft. Wenn das SDK das CMM nach Materialien zur Verschlüsselung oder Entschlüsselung fragt, ruft das CMM die Materialien von seinem Schlüsselbund oder Hauptschlüsselanbieter ab. In Java und Python verwendet der CMM die Masterschlüssel zum Generieren, Verschlüsseln oder Entschlüsseln der Datenschlüssel. In C und C generiert und JavaScript verschlüsselt der Schlüsselbund die kryptografischen Materialien und gibt sie zurück.
+ Ein Cache-CMM ist einem Cache, z. B. einem [lokalen Cache](#simplecache), und einem zugrunde liegenden CMM zugeordnet. Wenn das SDK den Cache-CMM nach kryptografischem Material fragt, versucht das Caching-CMM, diese aus dem Cache abzurufen. Wenn es keine Übereinstimmung finden kann, fragt das Cache-CMM das zugrundeliegende CMM nach den Materialien. Anschließend speichert er die neuen kryptografischen Materialien im Cache, bevor er sie an den Aufrufer zurückgibt. 

Das CMM für die Zwischenspeicherung setzt außerdem [Sicherheitsschwellenwerte](thresholds.md) durch, die Sie für jeden Cache-Eintrag festlegen. Da die Sicherheitsschwellenwerte im Cache-CMM festgelegt und von diesem durchgesetzt werden, können Sie jeden kompatiblen Cache verwenden, auch wenn der Cache nicht für vertrauliches Material konzipiert ist.

## Was befinde sich in einem Datenschlüssel-Cache-Eintrag?
<a name="cache-entries"></a>

Das Datenschlüssel-Caching speichert Datenschlüssel und zugehörige kryptographische Materialien in einem Cache. Jeder Eintrag enthält die folgenden Elemente. Diese Informationen sind möglicherweise hilfreich, wenn Sie entscheiden, ob Sie die Funktion zum Zwischenspeichern von Datenschlüsseln verwenden möchten, und wenn Sie Sicherheitsschwellenwerte in einem Caching Cryptographic Materials Manager (Caching CMM) festlegen.

**Im Cache gespeicherte Einträge für Verschlüsselungsanfragen**  
Die Einträge, die einem Datenschlüssel-Cache durch eine Verschlüsselungsoperation hinzugefügt werden, umfassen folgende Elemente:
+ Klartext-Datenschlüssel
+ Verschlüsselte Datenschlüssel (einen oder mehrere)
+ [Verschlüsselungskontext](#caching-encryption-context) 
+ Nachrichtensignaturschlüssel (falls verwendet)
+ [Algorithmen-Paket](concepts.md#crypto-algorithm)
+ Metadaten, einschließlich Nutzungszähler für die Durchsetzung von Sicherheitsschwellenwerten

**Im Cache gespeicherte Einträge für Entschlüsselungsanfragen**  
Die Einträge, die einem Datenschlüssel-Cache durch eine Entschlüsselungsoperation hinzugefügt werden, umfassen folgende Elemente:
+ Klartext-Datenschlüssel
+ Signaturverifizierungsschlüssel (falls verwendet)
+ Metadaten, einschließlich Nutzungszähler für die Durchsetzung von Sicherheitsschwellenwerten

## Verschlüsselungskontext: Wie Cache-Einträge ausgewählt werden
<a name="caching-encryption-context"></a>

Sie können in jeder Anfrage zur Verschlüsselung von Daten einen Verschlüsselungskontext angeben. Der Verschlüsselungskontext spielt eine spezielle Rolle beim Datenschlüssel-Caching. Damit können Sie Untergruppen von Datenschlüsseln in Ihrem Cache erstellen, auch wenn die Datenschlüssel aus demselben CMM für die Zwischenspeicherung stammen.

Ein [Verschlüsselungskontext](concepts.md#encryption-context) ist eine Gruppe von Schlüssel/Wert-Paaren mit zufälligen, nicht geheimen Daten. Bei der Entschlüsselung wird der Verschlüsselungskontext kryptographisch an die verschlüsselten Daten, sodass derselbe Verschlüsselungskontext zur Entschlüsselung der Daten benötigt wird. In der AWS Encryption SDK wird der Verschlüsselungskontext in der [verschlüsselten Nachricht mit den verschlüsselten](concepts.md#message) Daten und Datenschlüsseln gespeichert. 

Wenn Sie einen Datenschlüssel-Cache verwenden, können Sie auch den Verschlüsselungskontext verwenden, um bestimmte im Cache gespeicherte Datenschlüssel für Ihre Verschlüsselungsvorgänge auszuwählen. Der Verschlüsselungskontext wird im Cache-Eintrag mit dem Datenschlüssel gespeichert (er ist Teil der Cache-Eintrag-ID). Im Cache gespeicherte Datenschlüssel werden nur wiederverwendet, wenn ihre Verschlüsselungskontexte übereinstimmen. Wenn Sie bestimmte Datenschlüssel für eine Verschlüsselungsanfrage wiederverwenden möchten, geben Sie den gleichen Verschlüsselungskontext an. Wenn Sie diese Datenschlüssel vermeiden möchten, geben Sie einen anderen Verschlüsselungskontext an. 

Der Verschlüsselungskontext ist immer optional, wird aber empfohlen. Wenn Sie in Ihrer Anfrage keinen Verschlüsselungskontext angeben, wird ein leerer Verschlüsselungskontext in die Cache-Eintrag-ID aufgenommen und jeder Anfrage zugeordnet.

## Benutzt meine Anwendung zwischengespeicherte Datenschlüssel?
<a name="caching-effect"></a>

Das Datenschlüssel-Caching ist eine Optimierungsstrategie, die für bestimmte Anwendungen und Workloads sehr effektiv ist. Da es jedoch ein gewisses Risiko mit sich bringt, ist es wichtig zu bestimmen, wie effektiv es für Ihre Situation ist, und dann zu entscheiden, ob der Nutzen die Risiken überwiegt.

Da das Datenschlüssel-Caching Datenschlüssel wiederverwendet, ist der offensichtlichste Effekt die Verringerung der Anzahl der Aufrufe, um neue Datenschlüssel zu generieren. Wenn das Zwischenspeichern von Datenschlüsseln implementiert ist, wird AWS Encryption SDK die AWS KMS `GenerateDataKey` Operation nur aufgerufen, um den ursprünglichen Datenschlüssel zu erstellen, und wenn der Cache fehlt. Das Caching verbessert jedoch die Leistung nur in Anwendungen, die zahlreiche Datenschlüssel mit den gleichen Eigenschaften generieren, einschließlich des gleichen Verschlüsselungskontexts und des gleichen Algorithmen-Pakets.

Um festzustellen, ob Ihre Implementierung von tatsächlich Datenschlüssel aus dem Cache verwendet, probieren Sie die folgenden Techniken aus. AWS Encryption SDK 
+ Überprüfen Sie in den Protokollen Ihrer Master-Key-Infrastruktur die Häufigkeit von Aufrufen zur Erstellung neuer Datenschlüssel. Wenn das Datenschlüssel-Caching wirksam ist, sollte die Anzahl der Aufrufe zum Erstellen neuer Schlüssel spürbar fallen. Wenn Sie beispielsweise einen AWS KMS Hauptschlüsselanbieter oder einen Schlüsselbund verwenden, suchen Sie in den CloudTrail Protokollen nach [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)Anrufen. 
+ Vergleichen Sie die [verschlüsselten Nachrichten](concepts.md#message), die das AWS Encryption SDK als Antwort auf verschiedene Verschlüsselungsanforderungen zurückgibt. Wenn Sie beispielsweise den verwenden AWS-Verschlüsselungs-SDK for Java, vergleichen Sie das [ParsedCiphertext](https://aws.github.io/aws-encryption-sdk-java/com/amazonaws/encryptionsdk/ParsedCiphertext.html)Objekt aus verschiedenen Verschlüsselungsaufrufen. Vergleichen Sie in der AWS-Verschlüsselungs-SDK for JavaScript den Inhalt der `encryptedDataKeys` Eigenschaft von. [MessageHeader](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/serialize/src/types.ts#L21) Wenn Datenschlüssel wiederverwendet werden, sind die verschlüsselten Datenschlüssel in der verschlüsselten Nachricht identisch.

# Beispiel für das Datenschlüssel-Caching
<a name="sample-cache-example"></a>

In diesem Beispiel wird das [Zwischenspeichern von Datenschlüsseln](data-key-caching.md) mit einem [lokalen Cache](data-caching-details.md#simplecache) verwendet, um eine Anwendung zu beschleunigen, in der von mehreren Geräten generierte Daten verschlüsselt und in verschiedenen Regionen gespeichert werden.

In diesem Szenario generieren mehrere Datenproduzenten Daten, verschlüsseln sie und schreiben in jeder Region in einen [Kinesis-Stream](https://aws.amazon.com/kinesis/streams/). [AWS Lambda](https://aws.amazon.com/lambda/)Funktionen (Verbraucher) entschlüsseln die Streams und schreiben Klartextdaten in eine DynamoDB-Tabelle in der Region. [Datenproduzenten und -verbraucher verwenden den AWS Encryption SDK und einen AWS KMS Hauptschlüsselanbieter.](concepts.md#master-key-provider) Um die Anzahl der Aufrufe an KMS zu reduzieren, verfügt jeder Hersteller und Verbraucher über einen eigenen lokalen Cache.

Den Quellcode für diese Beispiele finden Sie in [Java und Python](sample-cache-example-code.md). Das Beispiel enthält auch eine CloudFormation Vorlage, die die Ressourcen für die Beispiele definiert.

![\[Dieses Diagramm zeigt AWS KMS, wie Datenproduzenten und Verbraucher Amazon Kinesis Data Streams und Amazon DynamoDB verwenden.\]](http://docs.aws.amazon.com/de_de/encryption-sdk/latest/developer-guide/images/simplecache-example.png)


## Lokale Cache-Ergebnisse
<a name="caching-example-impact"></a>

Die folgende Tabelle zeigt, dass ein lokaler Cache die Gesamtzahl der Aufrufe an KMS (pro Sekunde pro Region) in diesem Beispiel auf 1% seines ursprünglichen Werts reduziert.


**Produzentenanfragen**  
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/encryption-sdk/latest/developer-guide/sample-cache-example.html)


**Konsumentenanfragen**  
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/encryption-sdk/latest/developer-guide/sample-cache-example.html)

# Beispielcode für das Zwischenspeichern von Datenschlüsseln
<a name="sample-cache-example-code"></a>

Dieses Codebeispiel erstellt eine einfache Implementierung von Datenschlüssel-Caching mit einem [lokalen Cache](data-caching-details.md#simplecache) in Java und Python. Der Code erstellt zwei Instanzen eines lokalen Caches: eine für [Datenproduzenten](#caching-producer), die Daten verschlüsseln, und eine weitere für [Datenverbraucher](#caching-consumer) (AWS Lambda Funktionen), die Daten entschlüsseln. Einzelheiten zur Implementierung von Datenschlüssel-Caching in den einzelnen Sprachen finden Sie in der [Javadoc](https://aws.github.io/aws-encryption-sdk-java/) - und [Python-Dokumentation](https://aws-encryption-sdk-python.readthedocs.io/en/latest/) für. AWS Encryption SDK

Das Zwischenspeichern von Datenschlüsseln ist für alle [Programmiersprachen](programming-languages.md) verfügbar, die von unterstützt werden. AWS Encryption SDK 

Vollständige und getestete Beispiele für die Verwendung von Datenschlüssel-Caching in finden Sie unter AWS Encryption SDK:
+ C/C\$1\$1: [caching\$1cmm.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/caching_cmm.cpp) 
+ [Java: SimpleDataKeyCachingExample .java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/examples/java/com/amazonaws/crypto/examples/v2/SimpleDataKeyCachingExample.java)
+ JavaScript [Browser: caching\$1cmm.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/caching_cmm.ts) 
+ JavaScript Node.js: [caching\$1cmm.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-node/src/caching_cmm.ts) 
+ Python: [data\$1key\$1caching\$1basic.py](https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/legacy/data_key_caching_basic.py)

## Produzent
<a name="caching-producer"></a>

Der Producer ruft eine Map ab, konvertiert sie in JSON, verwendet sie, um sie AWS Encryption SDK zu verschlüsseln, und überträgt den Chiffretext-Datensatz jeweils in einen [Kinesis-Stream](https://aws.amazon.com/kinesis/streams/). AWS-Region

[[Der Code definiert einen [Manager für kryptografisches Material im Cache](data-caching-details.md#caching-cmm) (Caching CMM) und ordnet ihn einem lokalen Cache und einem zugrunde liegenden Hauptschlüsselanbieter zu.AWS KMS](concepts.md#master-key-provider)](data-caching-details.md#simplecache) Das zwischengespeicherte CMM speichert die Datenschlüssel (und das [zugehörige kryptografische](data-caching-details.md#cache-entries) Material) des Hauptschlüsselanbieters zwischen. Außerdem interagiert sie mit dem Cache im Namen des SDK und erzwingt die von Ihnen festgelegten Sicherheitsschwellenwerte. 

Da beim Aufruf der Verschlüsselungsmethode ein CMM angegeben wird, das zwischengespeichert wird, und nicht ein regulärer [Cryptographic Materials Manager (CMM)](concepts.md#crypt-materials-manager) oder Hauptschlüsselanbieter, wird bei der Verschlüsselung das Zwischenspeichern von Datenschlüsseln verwendet.

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

Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

```
/*
 * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
 * in compliance with the License. A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package com.amazonaws.crypto.examples.kinesisdatakeycaching;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.MasterKeyProvider;
import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache;
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey;
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
import com.amazonaws.encryptionsdk.multi.MultipleProviderFactory;
import com.amazonaws.util.json.Jackson;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kinesis.KinesisClient;
import software.amazon.awssdk.services.kms.KmsClient;

/**
 * Pushes data to Kinesis Streams in multiple Regions.
 */
public class MultiRegionRecordPusher {

    private static final long MAX_ENTRY_AGE_MILLISECONDS = 300000;
    private static final long MAX_ENTRY_USES = 100;
    private static final int MAX_CACHE_ENTRIES = 100;
    private final String streamName_;
    private final ArrayList<KinesisClient> kinesisClients_;
    private final CachingCryptoMaterialsManager cachingMaterialsManager_;
    private final AwsCrypto crypto_;

    /**
     * Creates an instance of this object with Kinesis clients for all target Regions and a cached
     * key provider containing KMS master keys in all target Regions.
     */
    public MultiRegionRecordPusher(final Region[] regions, final String kmsAliasName,
        final String streamName) {
        streamName_ = streamName;
        crypto_ = AwsCrypto.builder()
            .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
            .build();
        kinesisClients_ = new ArrayList<>();

        AwsCredentialsProvider credentialsProvider = DefaultCredentialsProvider.builder().build();

        // Build KmsMasterKey and AmazonKinesisClient objects for each target region
        List<KmsMasterKey> masterKeys = new ArrayList<>();
        for (Region region : regions) {
            kinesisClients_.add(KinesisClient.builder()
                .credentialsProvider(credentialsProvider)
                .region(region)
                .build());

            KmsMasterKey regionMasterKey = KmsMasterKeyProvider.builder()
                .defaultRegion(region)
                .builderSupplier(() -> KmsClient.builder().credentialsProvider(credentialsProvider))
                .buildStrict(kmsAliasName)
                .getMasterKey(kmsAliasName);

            masterKeys.add(regionMasterKey);
        }

        // Collect KmsMasterKey objects into single provider and add cache
        MasterKeyProvider<?> masterKeyProvider = MultipleProviderFactory.buildMultiProvider(
            KmsMasterKey.class,
            masterKeys
        );

        cachingMaterialsManager_ = CachingCryptoMaterialsManager.newBuilder()
            .withMasterKeyProvider(masterKeyProvider)
            .withCache(new LocalCryptoMaterialsCache(MAX_CACHE_ENTRIES))
            .withMaxAge(MAX_ENTRY_AGE_MILLISECONDS, TimeUnit.MILLISECONDS)
            .withMessageUseLimit(MAX_ENTRY_USES)
            .build();
    }

    /**
     * JSON serializes and encrypts the received record data and pushes it to all target streams.
     */
    public void putRecord(final Map<Object, Object> data) {
        String partitionKey = UUID.randomUUID().toString();
        Map<String, String> encryptionContext = new HashMap<>();
        encryptionContext.put("stream", streamName_);

        // JSON serialize data
        String jsonData = Jackson.toJsonString(data);

        // Encrypt data
        CryptoResult<byte[], ?> result = crypto_.encryptData(
            cachingMaterialsManager_,
            jsonData.getBytes(),
            encryptionContext
        );
        byte[] encryptedData = result.getResult();

        // Put records to Kinesis stream in all Regions
        for (KinesisClient regionalKinesisClient : kinesisClients_) {
            regionalKinesisClient.putRecord(builder ->
                builder.streamName(streamName_)
                    .data(SdkBytes.fromByteArray(encryptedData))
                    .partitionKey(partitionKey));
        }
    }
}
```

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

```
"""
Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
in compliance with the License. A copy of the License is located at
 
https://aws.amazon.com/apache-2-0/
 
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import json
import uuid
 
from aws_encryption_sdk import EncryptionSDKClient, StrictAwsKmsMasterKeyProvider, CachingCryptoMaterialsManager, LocalCryptoMaterialsCache, CommitmentPolicy
from aws_encryption_sdk.key_providers.kms import KMSMasterKey
import boto3
 
 
class MultiRegionRecordPusher(object):
    """Pushes data to Kinesis Streams in multiple Regions."""
    CACHE_CAPACITY = 100
    MAX_ENTRY_AGE_SECONDS = 300.0
    MAX_ENTRY_MESSAGES_ENCRYPTED = 100
 
    def __init__(self, regions, kms_alias_name, stream_name):
        self._kinesis_clients = []
        self._stream_name = stream_name
 
        # Set up EncryptionSDKClient
        _client = EncryptionSDKClient(CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
 
        # Set up KMSMasterKeyProvider with cache
        _key_provider = StrictAwsKmsMasterKeyProvider(kms_alias_name)
 
        # Add MasterKey and Kinesis client for each Region
        for region in regions:
            self._kinesis_clients.append(boto3.client('kinesis', region_name=region))
            regional_master_key = KMSMasterKey(
                client=boto3.client('kms', region_name=region),
                key_id=kms_alias_name
            )
            _key_provider.add_master_key_provider(regional_master_key)
 
        cache = LocalCryptoMaterialsCache(capacity=self.CACHE_CAPACITY)
        self._materials_manager = CachingCryptoMaterialsManager(
            master_key_provider=_key_provider,
            cache=cache,
            max_age=self.MAX_ENTRY_AGE_SECONDS,
            max_messages_encrypted=self.MAX_ENTRY_MESSAGES_ENCRYPTED
        )
 
    def put_record(self, record_data):
        """JSON serializes and encrypts the received record data and pushes it to all target streams.
 
        :param dict record_data: Data to write to stream
        """
        # Kinesis partition key to randomize write load across stream shards
        partition_key = uuid.uuid4().hex
 
        encryption_context = {'stream': self._stream_name}
 
        # JSON serialize data
        json_data = json.dumps(record_data)
 
        # Encrypt data
        encrypted_data, _header = _client.encrypt(
            source=json_data,
            materials_manager=self._materials_manager,
            encryption_context=encryption_context
        )
 
        # Put records to Kinesis stream in all Regions
        for client in self._kinesis_clients:
            client.put_record(
                StreamName=self._stream_name,
                Data=encrypted_data,
                PartitionKey=partition_key
            )
```

------

## Konsument
<a name="caching-consumer"></a>

Der Datenverbraucher ist eine [AWS Lambda](https://aws.amazon.com/lambda/)Funktion, die durch [Kinesis-Ereignisse](https://aws.amazon.com/kinesis/) ausgelöst wird. Es entschlüsselt und deserialisiert jeden Datensatz und schreibt den Klartext-Datensatz in eine [Amazon DynamoDB-Tabelle](https://aws.amazon.com/dynamodb/) in derselben Region.

Wie der Herstellercode ermöglicht auch der Verbrauchercode das Zwischenspeichern von Datenschlüsseln, indem er bei Aufrufen der Entschlüsselungsmethode einen Caching Cryptographic Materials Manager (Caching CMM) verwendet. 

*Der Java-Code erstellt einen Hauptschlüsselanbieter im strikten Modus mit einem bestimmten Wert.* AWS KMS key Der strikte Modus ist beim Entschlüsseln nicht erforderlich, hat sich aber [bewährt](best-practices.md#strict-discovery-mode). Der Python-Code verwendet den *Discovery-Modus*, der es ermöglicht, jeden Wrapping-Schlüssel zu AWS Encryption SDK verwenden, der einen Datenschlüssel verschlüsselt hat, um ihn zu entschlüsseln.

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

Im folgenden Beispiel wird Version 2 verwendet. *x* der AWS-Verschlüsselungs-SDK for Java. Ausführung 3. *x* of the AWS-Verschlüsselungs-SDK for Java verbietet das CMM zum Zwischenspeichern von Datenschlüsseln. Mit Version 3. *x*, Sie können auch den [AWS KMS hierarchischen Schlüsselbund](use-hierarchical-keyring.md) verwenden, eine alternative Lösung zum Zwischenspeichern kryptografischer Materialien.

Dieser Code erstellt einen Hauptschlüsselanbieter für die Entschlüsselung im strikten Modus. Er AWS Encryption SDK kann nur den von AWS KMS keys Ihnen angegebenen verwenden, um Ihre Nachricht zu entschlüsseln.

```
/*
 * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
 * in compliance with the License. A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package com.amazonaws.crypto.examples.kinesisdatakeycaching;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache;
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent.KinesisEventRecord;
import com.amazonaws.util.BinaryUtils;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;

/**
 * Decrypts all incoming Kinesis records and writes records to DynamoDB.
 */
public class LambdaDecryptAndWrite {

    private static final long MAX_ENTRY_AGE_MILLISECONDS = 600000;
    private static final int MAX_CACHE_ENTRIES = 100;
    private final CachingCryptoMaterialsManager cachingMaterialsManager_;
    private final AwsCrypto crypto_;
    private final DynamoDbTable<Item> table_;

    /**
     * Because the cache is used only for decryption, the code doesn't set the max bytes or max
     * message security thresholds that are enforced only on on data keys used for encryption.
     */
    public LambdaDecryptAndWrite() {
        String kmsKeyArn = System.getenv("CMK_ARN");
        cachingMaterialsManager_ = CachingCryptoMaterialsManager.newBuilder()
            .withMasterKeyProvider(KmsMasterKeyProvider.builder().buildStrict(kmsKeyArn))
            .withCache(new LocalCryptoMaterialsCache(MAX_CACHE_ENTRIES))
            .withMaxAge(MAX_ENTRY_AGE_MILLISECONDS, TimeUnit.MILLISECONDS)
            .build();

        crypto_ = AwsCrypto.builder()
            .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
            .build();

        String tableName = System.getenv("TABLE_NAME");
        DynamoDbEnhancedClient dynamodb = DynamoDbEnhancedClient.builder().build();
        table_ = dynamodb.table(tableName, TableSchema.fromClass(Item.class));
    }

    /**
     * @param event
     * @param context
     */
    public void handleRequest(KinesisEvent event, Context context)
        throws UnsupportedEncodingException {
        for (KinesisEventRecord record : event.getRecords()) {
            ByteBuffer ciphertextBuffer = record.getKinesis().getData();
            byte[] ciphertext = BinaryUtils.copyAllBytesFrom(ciphertextBuffer);

            // Decrypt and unpack record
            CryptoResult<byte[], ?> plaintextResult = crypto_.decryptData(cachingMaterialsManager_,
                ciphertext);

            // Verify the encryption context value
            String streamArn = record.getEventSourceARN();
            String streamName = streamArn.substring(streamArn.indexOf("/") + 1);
            if (!streamName.equals(plaintextResult.getEncryptionContext().get("stream"))) {
                throw new IllegalStateException("Wrong Encryption Context!");
            }

            // Write record to DynamoDB
            String jsonItem = new String(plaintextResult.getResult(), StandardCharsets.UTF_8);
            System.out.println(jsonItem);
            table_.putItem(Item.fromJSON(jsonItem));
        }
    }

    private static class Item {

        static Item fromJSON(String jsonText) {
            // Parse JSON and create new Item
            return new Item();
        }
    }
}
```

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

Dieser Python-Code wird mit einem Master-Key-Anbieter im Discovery-Modus entschlüsselt. Es ermöglicht die AWS Encryption SDK Verwendung eines beliebigen Umschließungsschlüssels, der einen Datenschlüssel verschlüsselt hat, um ihn zu entschlüsseln. Der strikte Modus, in dem Sie die Umschließungsschlüssel angeben, die für die Entschlüsselung verwendet werden können, ist eine [bewährte](best-practices.md#strict-discovery-mode) Methode.

```
"""
Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
in compliance with the License. A copy of the License is located at
 
https://aws.amazon.com/apache-2-0/
 
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import base64
import json
import logging
import os
 
from aws_encryption_sdk import EncryptionSDKClient, DiscoveryAwsKmsMasterKeyProvider, CachingCryptoMaterialsManager, LocalCryptoMaterialsCache, CommitmentPolicy
import boto3
 
_LOGGER = logging.getLogger(__name__)
_is_setup = False
CACHE_CAPACITY = 100
MAX_ENTRY_AGE_SECONDS = 600.0
 
def setup():
    """Sets up clients that should persist across Lambda invocations."""
    global encryption_sdk_client
    encryption_sdk_client = EncryptionSDKClient(CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
 
    global materials_manager
    key_provider = DiscoveryAwsKmsMasterKeyProvider()
    cache = LocalCryptoMaterialsCache(capacity=CACHE_CAPACITY)
           
    #  Because the cache is used only for decryption, the code doesn't set
    #   the max bytes or max message security thresholds that are enforced
    #   only on on data keys used for encryption.
    materials_manager = CachingCryptoMaterialsManager(
        master_key_provider=key_provider,
        cache=cache,
        max_age=MAX_ENTRY_AGE_SECONDS
    )
    global table
    table_name = os.environ.get('TABLE_NAME')
    table = boto3.resource('dynamodb').Table(table_name)
    global _is_setup
    _is_setup = True
 
 
def lambda_handler(event, context):
    """Decrypts all incoming Kinesis records and writes records to DynamoDB."""
    _LOGGER.debug('New event:')
    _LOGGER.debug(event)
    if not _is_setup:
        setup()
    with table.batch_writer() as batch:
        for record in event.get('Records', []):
            # Record data base64-encoded by Kinesis
            ciphertext = base64.b64decode(record['kinesis']['data'])
 
            # Decrypt and unpack record
            plaintext, header = encryption_sdk_client.decrypt(
                source=ciphertext,
                materials_manager=materials_manager
            )
            item = json.loads(plaintext)
 
            # Verify the encryption context value
            stream_name = record['eventSourceARN'].split('/', 1)[1]
            if stream_name != header.encryption_context['stream']:
                raise ValueError('Wrong Encryption Context!')
 
            # Write record to DynamoDB
            batch.put_item(Item=item)
```

------

# Beispiel für das Zwischenspeichern von Datenschlüsseln: Vorlage CloudFormation
<a name="sample-cache-example-cloudformation"></a>

Diese CloudFormation Vorlage richtet alle erforderlichen AWS Ressourcen ein, um das [Beispiel für das Zwischenspeichern von Datenschlüsseln](sample-cache-example.md) zu reproduzieren.

------
#### [ JSON ]

```
{
    "Parameters": {
        "SourceCodeBucket": {
            "Type": "String",
            "Description": "S3 bucket containing Lambda source code zip files"
        },
        "PythonLambdaS3Key": {
            "Type": "String",
            "Description": "S3 key containing Python Lambda source code zip file"
        },
        "PythonLambdaObjectVersionId": {
            "Type": "String",
            "Description": "S3 version id for S3 key containing Python Lambda source code zip file"
        },
        "JavaLambdaS3Key": {
            "Type": "String",
            "Description": "S3 key containing Python Lambda source code zip file"
        },
        "JavaLambdaObjectVersionId": {
            "Type": "String",
            "Description": "S3 version id for S3 key containing Python Lambda source code zip file"
        },
        "KeyAliasSuffix": {
            "Type": "String",
            "Description": "Suffix to use for KMS key Alias (ie: alias/KeyAliasSuffix)"
        },
        "StreamName": {
            "Type": "String",
            "Description": "Name to use for Kinesis Stream"
        }
    },
    "Resources": {
        "InputStream": {
            "Type": "AWS::Kinesis::Stream",
            "Properties": {
                "Name": {
                    "Ref": "StreamName"
                },
                "ShardCount": 2
            }
        },
        "PythonLambdaOutputTable": {
            "Type": "AWS::DynamoDB::Table",
            "Properties": {
                "AttributeDefinitions": [
                    {
                        "AttributeName": "id",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "id",
                        "KeyType": "HASH"
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                }
            }
        },
        "PythonLambdaRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": "lambda.amazonaws.com"
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                },
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
                ],
                "Policies": [
                    {
                        "PolicyName": "PythonLambdaAccess",
                        "PolicyDocument": {
                            "Version": "2012-10-17",		 	 	 
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "dynamodb:DescribeTable",
                                        "dynamodb:BatchWriteItem"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${PythonLambdaOutputTable}"
                                    }
                                },
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "dynamodb:PutItem"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${PythonLambdaOutputTable}*"
                                    }
                                },
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "kinesis:GetRecords",
                                        "kinesis:GetShardIterator",
                                        "kinesis:DescribeStream",
                                        "kinesis:ListStreams"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}"
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "PythonLambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Description": "Python consumer",
                "Runtime": "python2.7",
                "MemorySize": 512,
                "Timeout": 90,
                "Role": {
                    "Fn::GetAtt": [
                        "PythonLambdaRole",
                        "Arn"
                    ]
                },
                "Handler": "aws_crypto_examples.kinesis_datakey_caching.consumer.lambda_handler",
                "Code": {
                    "S3Bucket": {
                        "Ref": "SourceCodeBucket"
                    },
                    "S3Key": {
                        "Ref": "PythonLambdaS3Key"
                    },
                    "S3ObjectVersion": {
                        "Ref": "PythonLambdaObjectVersionId"
                    }
                },
                "Environment": {
                    "Variables": {
                        "TABLE_NAME": {
                            "Ref": "PythonLambdaOutputTable"
                        }
                    }
                }
            }
        },
        "PythonLambdaSourceMapping": {
            "Type": "AWS::Lambda::EventSourceMapping",
            "Properties": {
                "BatchSize": 1,
                "Enabled": true,
                "EventSourceArn": {
                    "Fn::Sub": "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}"
                },
                "FunctionName": {
                    "Ref": "PythonLambdaFunction"
                },
                "StartingPosition": "TRIM_HORIZON"
            }
        },
        "JavaLambdaOutputTable": {
            "Type": "AWS::DynamoDB::Table",
            "Properties": {
                "AttributeDefinitions": [
                    {
                        "AttributeName": "id",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "id",
                        "KeyType": "HASH"
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                }
            }
        },
        "JavaLambdaRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": "lambda.amazonaws.com"
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                },
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
                ],
                "Policies": [
                    {
                        "PolicyName": "JavaLambdaAccess",
                        "PolicyDocument": {
                            "Version": "2012-10-17",		 	 	 
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "dynamodb:DescribeTable",
                                        "dynamodb:BatchWriteItem"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${JavaLambdaOutputTable}"
                                    }
                                },
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "dynamodb:PutItem"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${JavaLambdaOutputTable}*"
                                    }
                                },
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "kinesis:GetRecords",
                                        "kinesis:GetShardIterator",
                                        "kinesis:DescribeStream",
                                        "kinesis:ListStreams"
                                    ],
                                    "Resource": {
                                        "Fn::Sub": "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}"
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "JavaLambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Description": "Java consumer",
                "Runtime": "java8",
                "MemorySize": 512,
                "Timeout": 90,
                "Role": {
                    "Fn::GetAtt": [
                        "JavaLambdaRole",
                        "Arn"
                    ]
                },
                "Handler": "com.amazonaws.crypto.examples.kinesisdatakeycaching.LambdaDecryptAndWrite::handleRequest",
                "Code": {
                    "S3Bucket": {
                        "Ref": "SourceCodeBucket"
                    },
                    "S3Key": {
                        "Ref": "JavaLambdaS3Key"
                    },
                    "S3ObjectVersion": {
                        "Ref": "JavaLambdaObjectVersionId"
                    }
                },
                "Environment": {
                    "Variables": {
                        "TABLE_NAME": {
                            "Ref": "JavaLambdaOutputTable"
                        },
                        "CMK_ARN": {
                            "Fn::GetAtt": [
                                "RegionKinesisCMK",
                                "Arn"
                            ]
                        }
                    }
                }
            }
        },
        "JavaLambdaSourceMapping": {
            "Type": "AWS::Lambda::EventSourceMapping",
            "Properties": {
                "BatchSize": 1,
                "Enabled": true,
                "EventSourceArn": {
                    "Fn::Sub": "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}"
                },
                "FunctionName": {
                    "Ref": "JavaLambdaFunction"
                },
                "StartingPosition": "TRIM_HORIZON"
            }
        },
        "RegionKinesisCMK": {
            "Type": "AWS::KMS::Key",
            "Properties": {
                "Description": "Used to encrypt data passing through Kinesis Stream in this region",
                "Enabled": true,
                "KeyPolicy": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "AWS": {
                                    "Fn::Sub": "arn:aws:iam::${AWS::AccountId}:root"
                                }
                            },
                            "Action": [
                                "kms:Encrypt",
                                "kms:GenerateDataKey",
                                "kms:CreateAlias",
                                "kms:DeleteAlias",
                                "kms:DescribeKey",
                                "kms:DisableKey",
                                "kms:EnableKey",
                                "kms:PutKeyPolicy",
                                "kms:ScheduleKeyDeletion",
                                "kms:UpdateAlias",
                                "kms:UpdateKeyDescription"
                            ],
                            "Resource": "*"
                        },
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "AWS": [
                                    {
                                        "Fn::GetAtt": [
                                            "PythonLambdaRole",
                                            "Arn"
                                        ]
                                    },
                                    {
                                        "Fn::GetAtt": [
                                            "JavaLambdaRole",
                                            "Arn"
                                        ]
                                    }
                                ]
                            },
                            "Action": "kms:Decrypt",
                            "Resource": "*"
                        }
                    ]
                }
            }
        },
        "RegionKinesisCMKAlias": {
            "Type": "AWS::KMS::Alias",
            "Properties": {
                "AliasName": {
                    "Fn::Sub": "alias/${KeyAliasSuffix}"
                },
                "TargetKeyId": {
                    "Ref": "RegionKinesisCMK"
                }
            }
        }
    }
}
```

------
#### [ YAML ]

```
Parameters:
    SourceCodeBucket:
        Type: String
        Description: S3 bucket containing Lambda source code zip files
    PythonLambdaS3Key:
        Type: String
        Description: S3 key containing Python Lambda source code zip file
    PythonLambdaObjectVersionId:
        Type: String
        Description: S3 version id for S3 key containing Python Lambda source code zip file
    JavaLambdaS3Key:
        Type: String
        Description: S3 key containing Python Lambda source code zip file
    JavaLambdaObjectVersionId:
        Type: String
        Description: S3 version id for S3 key containing Python Lambda source code zip file
    KeyAliasSuffix:
        Type: String
        Description: 'Suffix to use for KMS CMK Alias (ie: alias/<KeyAliasSuffix>)'
    StreamName:
        Type: String
        Description: Name to use for Kinesis Stream
Resources:
    InputStream:
        Type: AWS::Kinesis::Stream
        Properties:
            Name: !Ref StreamName
            ShardCount: 2
    PythonLambdaOutputTable:
        Type: AWS::DynamoDB::Table
        Properties:
            AttributeDefinitions:
                -
                    AttributeName: id
                    AttributeType: S
            KeySchema:
                -
                    AttributeName: id
                    KeyType: HASH
            ProvisionedThroughput:
                ReadCapacityUnits: 1
                WriteCapacityUnits: 1
    PythonLambdaRole:
        Type: AWS::IAM::Role
        Properties:
            AssumeRolePolicyDocument:
                Version: 2012-10-17
                Statement:
                    -
                        Effect: Allow
                        Principal:
                            Service: lambda.amazonaws.com
                        Action: sts:AssumeRole
            ManagedPolicyArns:
                - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
            Policies:
                -
                    PolicyName: PythonLambdaAccess
                    PolicyDocument:
                        Version: 2012-10-17
                        Statement:
                            -
                                Effect: Allow
                                Action:
                                    - dynamodb:DescribeTable
                                    - dynamodb:BatchWriteItem
                                Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${PythonLambdaOutputTable}
                            -
                                Effect: Allow
                                Action:
                                    - dynamodb:PutItem
                                Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${PythonLambdaOutputTable}*
                            -
                                Effect: Allow
                                Action:
                                    - kinesis:GetRecords
                                    - kinesis:GetShardIterator
                                    - kinesis:DescribeStream
                                    - kinesis:ListStreams
                                Resource: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}
    PythonLambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
            Description: Python consumer
            Runtime: python2.7
            MemorySize: 512
            Timeout: 90
            Role: !GetAtt PythonLambdaRole.Arn
            Handler: aws_crypto_examples.kinesis_datakey_caching.consumer.lambda_handler
            Code:
                S3Bucket: !Ref SourceCodeBucket
                S3Key: !Ref PythonLambdaS3Key
                S3ObjectVersion: !Ref PythonLambdaObjectVersionId
            Environment:
                Variables:
                    TABLE_NAME: !Ref PythonLambdaOutputTable
    PythonLambdaSourceMapping:
        Type: AWS::Lambda::EventSourceMapping
        Properties:
            BatchSize: 1
            Enabled: true
            EventSourceArn: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}
            FunctionName: !Ref PythonLambdaFunction
            StartingPosition: TRIM_HORIZON
    JavaLambdaOutputTable:
        Type: AWS::DynamoDB::Table
        Properties:
            AttributeDefinitions:
                -
                    AttributeName: id
                    AttributeType: S
            KeySchema:
                -
                    AttributeName: id
                    KeyType: HASH
            ProvisionedThroughput:
                ReadCapacityUnits: 1
                WriteCapacityUnits: 1
    JavaLambdaRole:
        Type: AWS::IAM::Role
        Properties:
            AssumeRolePolicyDocument:
                Version: 2012-10-17
                Statement:
                    -
                        Effect: Allow
                        Principal:
                            Service: lambda.amazonaws.com
                        Action: sts:AssumeRole
            ManagedPolicyArns:
                - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
            Policies:
                -
                    PolicyName: JavaLambdaAccess
                    PolicyDocument:
                        Version: 2012-10-17
                        Statement:
                            -
                                Effect: Allow
                                Action:
                                    - dynamodb:DescribeTable
                                    - dynamodb:BatchWriteItem
                                Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${JavaLambdaOutputTable}
                            -
                                Effect: Allow
                                Action:
                                    - dynamodb:PutItem
                                Resource: !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${JavaLambdaOutputTable}*
                            -
                                Effect: Allow
                                Action:
                                    - kinesis:GetRecords
                                    - kinesis:GetShardIterator
                                    - kinesis:DescribeStream
                                    - kinesis:ListStreams
                                Resource: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}
    JavaLambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
            Description: Java consumer
            Runtime: java8
            MemorySize: 512
            Timeout: 90
            Role: !GetAtt JavaLambdaRole.Arn
            Handler: com.amazonaws.crypto.examples.kinesisdatakeycaching.LambdaDecryptAndWrite::handleRequest
            Code:
                S3Bucket: !Ref SourceCodeBucket
                S3Key: !Ref JavaLambdaS3Key
                S3ObjectVersion: !Ref JavaLambdaObjectVersionId
            Environment:
                Variables:
                    TABLE_NAME: !Ref JavaLambdaOutputTable
                    CMK_ARN: !GetAtt RegionKinesisCMK.Arn
    JavaLambdaSourceMapping:
        Type: AWS::Lambda::EventSourceMapping
        Properties:
            BatchSize: 1
            Enabled: true
            EventSourceArn: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${InputStream}
            FunctionName: !Ref JavaLambdaFunction
            StartingPosition: TRIM_HORIZON
    RegionKinesisCMK:
        Type: AWS::KMS::Key
        Properties:
            Description: Used to encrypt data passing through Kinesis Stream in this region
            Enabled: true
            KeyPolicy:
                Version: 2012-10-17
                Statement:
                    -
                        Effect: Allow
                        Principal:
                            AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
                        Action:
                            # Data plane actions
                            - kms:Encrypt
                            - kms:GenerateDataKey
                            # Control plane actions
                            - kms:CreateAlias
                            - kms:DeleteAlias
                            - kms:DescribeKey
                            - kms:DisableKey
                            - kms:EnableKey
                            - kms:PutKeyPolicy
                            - kms:ScheduleKeyDeletion
                            - kms:UpdateAlias
                            - kms:UpdateKeyDescription
                        Resource: '*'
                    -
                        Effect: Allow
                        Principal:
                            AWS:
                                - !GetAtt PythonLambdaRole.Arn
                                - !GetAtt JavaLambdaRole.Arn
                        Action: kms:Decrypt
                        Resource: '*'
    RegionKinesisCMKAlias:
        Type: AWS::KMS::Alias
        Properties:
            AliasName: !Sub alias/${KeyAliasSuffix}
            TargetKeyId: !Ref RegionKinesisCMK
```

------