AWS KMS Porte-clés hiérarchiques - AWS Encryption SDK

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

AWS KMS Porte-clés hiérarchiques

Important

Le porte-clés AWS KMS hiérarchique n'est pris en charge que par la version 4. x du AWS Encryption SDK formulaire. NETet version 3. x du Kit SDK de chiffrement AWS pour Java.

Avec le trousseau de clés AWS KMS hiérarchique, vous pouvez protéger vos documents cryptographiques sous une KMS clé de chiffrement symétrique sans avoir à appeler AWS KMS chaque fois que vous cryptez ou déchiffrez des données. Il s'agit d'un bon choix pour les applications qui doivent minimiser les appels AWS KMS, ainsi que pour les applications qui peuvent réutiliser certains matériels cryptographiques sans enfreindre leurs exigences de sécurité.

Le trousseau de clés hiérarchique est une solution de mise en cache des matériaux cryptographiques qui réduit le nombre d' AWS KMS appels en utilisant des clés de branche AWS KMS protégées conservées dans une table Amazon DynamoDB, puis en mettant en cache localement les éléments clés de branche utilisés dans les opérations de chiffrement et de déchiffrement. La table DynamoDB sert de magasin de clés de branche qui gère et protège les clés de branche. Il stocke la clé de branche active et toutes les versions précédentes de la clé de branche. La clé de branche active est la version de clé de branche la plus récente. Le trousseau de clés hiérarchique utilise une clé de données unique pour chiffrer chaque message et chiffre chaque clé de données avec une clé d'encapsulation unique dérivée de la clé de branche active. Le trousseau de clés hiérarchique dépend de la hiérarchie établie entre les clés de branche actives et leurs clés d'encapsulation dérivées.

Le trousseau de clés hiérarchique utilise généralement chaque version de clé de branche pour satisfaire plusieurs demandes. Mais vous contrôlez la mesure dans laquelle les clés de branche actives sont réutilisées et vous déterminez la fréquence à laquelle la clé de branche active est pivotée. La version active de la clé de branche reste active jusqu'à ce que vous la fassiez pivoter. Les versions précédentes de la clé de branche active ne seront pas utilisées pour effectuer des opérations de chiffrement, mais elles peuvent toujours être interrogées et utilisées dans des opérations de déchiffrement.

Lorsque vous instanciez le trousseau de clés hiérarchique, il crée un cache local. Vous spécifiez une limite de cache qui définit la durée maximale pendant laquelle les éléments clés de branche sont stockés dans le cache local avant leur expiration et leur expulsion du cache. Le trousseau de clés hiérarchique effectue un AWS KMS appel pour déchiffrer la clé de branche et assembler les matériaux de la clé de branche la première fois que a branch-key-id est spécifié dans une opération. Les éléments clés de branche sont ensuite stockés dans le cache local et réutilisés pour toutes les opérations de chiffrement et de déchiffrement qui le spécifient branch-key-id jusqu'à l'expiration de la limite de cache. Le stockage des éléments clés de branche dans le cache local réduit le nombre d' AWS KMS appels. Par exemple, considérez une limite de cache de 15 minutes. Si vous effectuez 10 000 opérations de chiffrement dans cette limite de cache, le trousseau de AWS KMS clés traditionnel devra effectuer 10 000 AWS KMS appels pour satisfaire 10 000 opérations de chiffrement. Si vous en avez un actifbranch-key-id, le trousseau de clés hiérarchique n'a besoin que d'un seul AWS KMS appel pour satisfaire 10 000 opérations de chiffrement.

Le cache local se compose de deux partitions, l'une pour les opérations de chiffrement et l'autre pour les opérations de déchiffrement. La partition de chiffrement stocke les éléments de clé de branche assemblés à partir de la clé de branche active et les réutilise pour toutes les opérations de chiffrement jusqu'à l'expiration de la limite de cache. La partition de déchiffrement stocke les matériaux de clé de branche assemblés pour les autres versions de clé de branche identifiées lors des opérations de déchiffrement. La partition de déchiffrement peut stocker plusieurs versions de documents clés de branche actifs à la fois. Lorsqu'elle est configurée pour utiliser un fournisseur d'ID de clé de branche pour un environnement mutualisé, la partition de chiffrement peut également stocker plusieurs versions de matériaux de clé de branche à la fois. Pour plus d’informations, consultez Utilisation du trousseau de clés hiérarchique dans les environnements multilocataires.

Note

Toutes les mentions du porte-clés hiérarchique dans le AWS Encryption SDK font référence au porte-clés AWS KMS hiérarchique.

Comment ça marche

Les procédures pas à pas suivantes décrivent comment le trousseau de clés hiérarchique assemble le matériel de chiffrement et de déchiffrement, ainsi que les différents appels effectués par le trousseau de clés pour les opérations de chiffrement et de déchiffrement. Pour plus de détails techniques sur les processus de dérivation des clés d'encapsulation et de chiffrement des clés de données en texte clair, consultez la section Détails techniques du trousseau de clés AWS KMS hiérarchique.

Chiffrer et signer

La procédure pas à pas suivante décrit comment le trousseau de clés hiérarchique assemble les matériaux de chiffrement et en déduit une clé d'encapsulation unique.

  1. La méthode de cryptage demande au trousseau de clés hiérarchique le matériel de cryptage. Le trousseau de clés génère une clé de données en texte brut, puis vérifie s'il existe des éléments de branche valides dans le cache local pour générer la clé d'encapsulation. S'il existe des documents relatifs aux clés de succursale valides, le porte-clés passe à l'étape 5.

  2. S'il n'existe aucun matériel de clé de branche valide, le trousseau de clés hiérarchique interroge le magasin de clés de branche pour trouver la clé de branche active.

    1. Le magasin de clés de branche appelle AWS KMS pour déchiffrer la clé de branche active et renvoie la clé de branche active en texte clair. Les données identifiant la clé de branche active sont sérialisées pour fournir des données authentifiées supplémentaires (AAD) dans l'appel de déchiffrement à. AWS KMS

    2. Le magasin de clés de branche renvoie la clé de branche en texte brut et les données qui l'identifient, telles que la version de la clé de branche.

  3. Le trousseau de clés hiérarchique assemble les éléments clés de branche (version de clé de branche en texte clair et de clé de branche) et en stocke une copie dans le cache local.

  4. Le trousseau de clés hiérarchique déduit une clé d'encapsulation unique à partir de la clé de branche en texte brut et d'un sel aléatoire de 16 octets. Il utilise la clé d'encapsulation dérivée pour chiffrer une copie de la clé de données en texte brut.

La méthode de chiffrement utilise les matériaux de chiffrement pour chiffrer les données. Pour plus d'informations, consultez Comment AWS Encryption SDK crypte les données.

Déchiffrer et vérifier

La procédure pas à pas suivante décrit comment le trousseau de clés hiérarchique assemble le matériel de déchiffrement et déchiffre la clé de données chiffrée.

  1. La méthode de déchiffrement identifie la clé de données chiffrée à partir du message chiffré et la transmet au trousseau de clés hiérarchique.

  2. Le trousseau hiérarchique désérialise les données identifiant la clé de données chiffrée, y compris la version de la clé de branche, le sel de 16 octets et d'autres informations décrivant le mode de chiffrement de la clé de données.

    Pour plus d’informations, consultez AWS KMS Détails techniques du porte-clés hiérarchique.

  3. Le trousseau de clés hiérarchique vérifie si le cache local contient des éléments de clé de branche valides qui correspondent à la version de clé de branche identifiée à l'étape 2. S'il existe des documents relatifs aux clés de succursale valides, le porte-clés passe à l'étape 6.

  4. S'il n'existe aucun matériel de clé de branche valide, le trousseau de clés hiérarchique interroge le magasin de clés de branche pour trouver la clé de branche correspondant à la version de clé de branche identifiée à l'étape 2.

    1. Le magasin de clés de branche appelle AWS KMS pour déchiffrer la clé de branche et renvoie la clé de branche active en texte clair. Les données identifiant la clé de branche active sont sérialisées pour fournir des données authentifiées supplémentaires (AAD) dans l'appel de déchiffrement à. AWS KMS

    2. Le magasin de clés de branche renvoie la clé de branche en texte brut et les données qui l'identifient, telles que la version de la clé de branche.

  5. Le trousseau de clés hiérarchique assemble les éléments clés de branche (version de clé de branche en texte clair et de clé de branche) et en stocke une copie dans le cache local.

  6. Le trousseau de clés hiérarchique utilise les éléments de clé de branche assemblés et le sel de 16 octets identifié à l'étape 2 pour reproduire la clé d'encapsulation unique qui a chiffré la clé de données.

  7. Le trousseau de clés hiérarchique utilise la clé d'encapsulation reproduite pour déchiffrer la clé de données et renvoie la clé de données en texte brut.

Le procédé de déchiffrement utilise le matériel de déchiffrement et la clé de données en texte brut pour déchiffrer le message chiffré. Pour plus d'informations, voir Comment AWS Encryption SDK déchiffre un message chiffré.

Prérequis

AWS Encryption SDK Cela ne nécessite pas de Compte AWS et ne dépend d'aucun AWS service. Toutefois, le trousseau de clés hiérarchique dépend d'Amazon AWS KMS DynamoDB.

Pour utiliser un trousseau de clés hiérarchique, vous avez besoin d'un chiffrement symétrique AWS KMS key avec les autorisations KMS:Decrypt. Vous pouvez également utiliser une clé multirégionale de chiffrement symétrique. Pour des informations détaillées sur les autorisations pour AWS KMS keys, voir Authentification et contrôle d'accès dans le Guide du AWS Key Management Service développeur.

Avant de pouvoir créer et utiliser un trousseau de clés hiérarchique, vous devez créer votre magasin de clés de succursale et le remplir avec votre première clé de branche active.

Étape 1 : Configuration d'un nouveau service de stockage de clés

Le service de magasin de clés propose plusieurs API opérations, telles que CreateKeyStore etCreateKey, pour vous aider à réunir les prérequis relatifs au jeu de clés hiérarchique et à gérer le magasin de clés de votre succursale.

L'exemple suivant crée un service de stockage de clés. Vous devez spécifier un nom de table DynamoDB qui servira de nom à votre magasin de clés de branche, un nom logique pour le magasin de clés de branche et KMS la clé identifiant KMS la ARN clé qui protégera vos clés de branche.

Le nom du magasin de clés logique est lié de manière cryptographique à toutes les données stockées dans la table afin de simplifier les opérations de restauration DynamoDB. Le nom logique du magasin de clés peut être identique au nom de votre table DynamoDB, mais ce n'est pas obligatoire. Nous vous recommandons de spécifier le nom de votre table DynamoDB comme nom de table logique lorsque vous configurez votre service de banque de clés pour la première fois. Vous devez toujours spécifier le même nom de table logique. Si le nom de votre banque de clés de branche change après la restauration de votre table DynamoDB à partir d'une sauvegarde, le nom de la banque de clés logique correspond au nom de la table DynamoDB que vous spécifiez pour garantir que le trousseau de clés hiérarchique peut toujours accéder à votre magasin de clés de succursale.

Note

Le nom logique du magasin de clés est inclus dans le contexte de chiffrement de toutes les API opérations de service du magasin de clés appelées AWS KMS. Le contexte de chiffrement n'est pas secret, ses valeurs, y compris le nom du magasin de clés logiques, apparaissent en texte clair dans les journaux. AWS CloudTrail

C# / .NET
var kmsConfig = new KMSConfiguration { KmsKeyArn = kmsKeyArn }; var keystoreConfig = new KeyStoreConfig { KmsClient = new AmazonKeyManagementServiceClient(), KmsConfiguration = kmsConfig, DdbTableName = keyStoreName, DdbClient = new AmazonDynamoDBClient(), LogicalKeyStoreName = logicalKeyStoreName }; var keystore = new KeyStore(keystoreConfig);
Java
final KeyStore keystore = KeyStore.builder().KeyStoreConfig( KeyStoreConfig.builder() .ddbClient(DynamoDbClient.create()) .ddbTableName(keyStoreName) .logicalKeyStoreName(logicalKeyStoreName) .kmsClient(KmsClient.create()) .kmsConfiguration(KMSConfiguration.builder() .kmsKeyArn(kmsKeyArn) .build()) .build()).build();
Étape 2 : Appelez CreateKeyStore pour créer un magasin de clés de succursale

L'opération suivante crée le magasin de clés de branche qui conservera et protégera vos clés de branche.

C# / .NET
var createKeyStoreOutput = keystore.CreateKeyStore(new CreateKeyStoreInput());
Java
keystore.CreateKeyStore(CreateKeyStoreInput.builder().build());

L'CreateKeyStoreopération crée une table DynamoDB avec le nom de table que vous avez spécifié à l'étape 1 et les valeurs obligatoires suivantes.

Clé de partition Clé de tri
Table de base branch-key-id type
Note

Vous pouvez créer manuellement la table DynamoDB qui sert de magasin de clés de branche au lieu d'utiliser l'opération. CreateKeyStore Si vous choisissez de créer manuellement le magasin de clés de branche, vous devez spécifier les valeurs de chaîne suivantes pour la partition et les clés de tri :

  • Clé de partition: branch-key-id

  • Clé de tri: type

Étape 3 : Appelez CreateKey pour créer une nouvelle clé de branche active

L'opération suivante crée une nouvelle clé de branche active à l'aide de la KMS clé que vous avez spécifiée à l'étape 1 et ajoute la clé de branche active à la table DynamoDB que vous avez créée à l'étape 2.

Lorsque vous appelezCreateKey, vous pouvez choisir de spécifier les valeurs facultatives suivantes.

C# / .NET
var additionalEncryptionContext = new Dictionary<string, string>(); additionalEncryptionContext.Add("Additional Encryption Context for", "custom branch key id"); var branchKeyId = keystore.CreateKey(new CreateKeyInput { BranchKeyIdentifier = "custom-branch-key-id", // OPTIONAL EncryptionContext = additionalEncryptionContext // OPTIONAL });
Java
final Map<String, String> additionalEncryptionContext = Collections.singletonMap("Additional Encryption Context for", "custom branch key id"); final String BranchKey = keystore.CreateKey( CreateKeyInput.builder() .branchKeyIdentifier(custom-branch-key-id) //OPTIONAL .encryptionContext(additionalEncryptionContext) //OPTIONAL .build()).branchKeyIdentifier();

Tout d'abord, l'CreateKeyopération génère les valeurs suivantes.

Ensuite, l'CreateKeyopération appelle kms : GenerateDataKeyWithoutPlaintext en utilisant la requête suivante.

{ "EncryptionContext": { "branch-key-id" : "branch-key-id", "type" : "type", "create-time" : "timestamp", "logical-key-store-name" : "the logical table name for your branch key store", "kms-arn" : the KMS key ARN, "hierarchy-version" : "1", "aws-crypto-ec:contextKey": "contextValue" }, "KeyId": "the KMS key ARN you specified in Step 1", "NumberOfBytes": "32" }

Ensuite, l'CreateKeyopération appelle kms : ReEncrypt pour créer un enregistrement actif pour la clé de branche en mettant à jour le contexte de chiffrement.

Enfin, l'CreateKeyopération appelle ddb : TransactWriteItems pour écrire un nouvel élément qui conservera la clé de branche dans la table que vous avez créée à l'étape 2. L'article possède les attributs suivants.

{ "branch-key-id" : branch-key-id, "type" : "branch:ACTIVE", "enc" : the branch key returned by the GenerateDataKeyWithoutPlaintext call, "version": "branch:version:the branch key version UUID", "create-time" : "timestamp", "kms-arn" : "the KMS key ARN you specified in Step 1", "hierarchy-version" : "1", "aws-crypto-ec:contextKey": "contextValue" }

Création d'un porte-clés hiérarchique

Pour initialiser le trousseau de clés hiérarchique, vous devez fournir les valeurs suivantes :

  • Un nom de magasin clé de succursale

    Nom de la table DynamoDB que vous avez créée pour servir de magasin de clés de succursale.

  • Une limite de durée de vie du cache (TTL)

    Durée en secondes pendant laquelle une entrée de clé de branche dans le cache local peut être utilisée avant son expiration. Cette valeur doit être supérieure à zéro. Lorsque la limite de cache TTL expire, l'entrée est expulsée du cache local.

  • Un identifiant de clé de branche

    Le branch-key-id qui identifie la clé de succursale active dans votre magasin de clés de succursale.

    Note

    Pour initialiser le trousseau de clés hiérarchique pour une utilisation par plusieurs locataires, vous devez spécifier un fournisseur d'ID de clé de branche au lieu d'un. branch-key-id Pour plus d’informations, consultez Utilisation du trousseau de clés hiérarchique dans les environnements multilocataires.

  • (Facultatif) Un cache

    Si vous souhaitez personnaliser le type de cache ou le nombre d'entrées clés de branche pouvant être stockées dans le cache local, spécifiez le type de cache et la capacité d'entrée lorsque vous initialisez le trousseau de clés.

    Le type de cache définit le modèle de threading. Le trousseau de clés hiérarchique fournit trois types de cache compatibles avec les environnements multilocataires : Default,, MultiThreaded. StormTracking

    Si vous ne spécifiez pas de cache, le trousseau de clés hiérarchique utilise automatiquement le type de cache par défaut et définit la capacité d'entrée à 1 000.

    Default (Recommended)

    Pour la plupart des utilisateurs, le cache par défaut répond à leurs exigences en matière de threading. Le cache par défaut est conçu pour prendre en charge les environnements fortement multithread. Lorsqu'une entrée de matériel clé de branche expire, le cache par défaut empêche plusieurs threads d'appeler AWS KMS et Amazon DynamoDB en notifiant à un thread que l'entrée de matériel clé de branche va expirer 10 secondes à l'avance. Cela garantit qu'un seul thread envoie une demande AWS KMS pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un cache par défaut, spécifiez la valeur suivante :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    C#/. NET
    CacheType defaultCache = new CacheType { Default = new DefaultCache{EntryCapacity = 100} };
    Java
    .cache(CacheType.builder() .Default(DefaultCache.builder() .entryCapacity(100) .build())

    La valeur par défaut et StormTracking les caches prennent en charge le même modèle de thread, mais il suffit de spécifier la capacité d'entrée pour initialiser le trousseau de clés hiérarchique avec le cache par défaut. Pour des personnalisations de cache plus détaillées, utilisez le StormTracking cache.

    MultiThreaded

    Le MultiThreaded cache peut être utilisé en toute sécurité dans les environnements multithread, mais il ne fournit aucune fonctionnalité permettant de minimiser les appels Amazon AWS KMS DynamoDB. Par conséquent, lorsqu'une entrée de contenu clé de branche expire, tous les fils de discussion seront avertis en même temps. Cela peut entraîner plusieurs AWS KMS appels pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un MultiThreaded cache, spécifiez les valeurs suivantes :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    • Taille de la queue d'élagage d'entrée : définit le nombre d'entrées à élaguer si la capacité d'entrée est atteinte.

    C#/. NET
    CacheType multithreadedCache = new CacheType { MultiThreaded = new MultiThreadedCache { EntryCapacity = 100, EntryPruningTailSize = 1 } };
    Java
    .cache(CacheType.builder() .MultiThreaded(MultiThreadedCache.builder() .entryCapacity(100) .entryPruningTailSize(1) .build())
    StormTracking

    Le StormTracking cache est conçu pour prendre en charge les environnements fortement multithread. Lorsqu'une entrée de matériel de clé de branche expire, le StormTracking cache empêche plusieurs threads d'appeler AWS KMS et Amazon DynamoDB en notifiant à un thread que l'entrée de documents de clé de branche va expirer à l'avance. Cela garantit qu'un seul thread envoie une demande AWS KMS pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un StormTracking cache, spécifiez les valeurs suivantes :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    • Taille de la queue d'élagage d'entrée : définit le nombre d'entrées de matériaux clés de branche à tailler à la fois.

      Valeur par défaut : 1 entrée

    • Période de grâce : définit le nombre de secondes avant l'expiration pendant lesquelles une tentative d'actualisation des documents clés de la branche est effectuée.

      Valeur par défaut : 10 secondes

    • Intervalle de grâce : définit le nombre de secondes entre les tentatives d'actualisation des éléments clés de la branche.

      Valeur par défaut : 1 seconde

    • Ventilateur : définit le nombre de tentatives simultanées qui peuvent être effectuées pour actualiser les documents clés de la branche.

      Valeur par défaut : 20 tentatives

    • In flight time to live (TTL) : définit le nombre de secondes avant l'expiration d'une tentative d'actualisation des éléments clés de la branche. Chaque fois que le cache revient NoSuchEntry en réponse à unGetCacheEntry, cette clé de branche est considérée comme étant en vol jusqu'à ce que la même clé soit écrite avec une PutCache entrée.

      Valeur par défaut : 20 secondes

    • Sommeil : définit le nombre de secondes pendant lesquelles un thread doit être mis en veille si le fanOut délai est dépassé.

      Valeur par défaut : 20 millisecondes

    C#/. NET
    CacheType stormTrackingCache = new CacheType { StormTracking = new StormTrackingCache { EntryCapacity = 100, EntryPruningTailSize = 1, FanOut = 20, GraceInterval = 1, GracePeriod = 10, InFlightTTL = 20, SleepMilli = 20 } };
    Java
    .cache(CacheType.builder() .MultiThreaded(MultiThreadedCache.builder() .entryCapacity(100) .entryPruningTailSize(1) .gracePeriod(10) .graceInterval(1) .fanOut(20) .inFlightTTL(20) .sleepMilli(20) .build())
  • (Facultatif) Une liste de jetons de subvention

    Si vous contrôlez l'accès à la KMS clé de votre trousseau hiérarchique avec des autorisations, vous devez fournir tous les jetons de subvention nécessaires lorsque vous initialisez le trousseau de clés.

L'exemple suivant initialise un jeu de clés hiérarchique avec une limite TLL de cache de 600 secondes et une capacité d'entrée de 1 000.

C# / .NET
// Instantiate the AWS Encryption SDK and material providers var mpl = new MaterialProviders(new MaterialProvidersConfig()); var esdk = new ESDK(new AwsEncryptionSdkConfig()); // Instantiate the keyring var createKeyringInput = new CreateAwsKmsHierarchicalKeyringInput { KeyStore = branchKeyStoreName, BranchKeyId = branch-key-id, Cache = new CacheType { Default = new DefaultCache{EntryCapacity = 1000} }, TtlSeconds = 600 };
Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder() .keyStore(branchKeyStoreName) .branchKeyId(branch-key-id) .ttlSeconds(600) .cache(CacheType.builder() //OPTIONAL .Default(DefaultCache.builder() .entryCapacity(1000) .build()) .build(); final Keyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);

Faites pivoter votre clé de branche active

Il ne peut y avoir qu'une seule version active à la fois pour chaque clé de branche. Le trousseau de clés hiérarchique utilise généralement chaque version de clé de branche active pour satisfaire plusieurs demandes. Mais vous contrôlez la mesure dans laquelle les clés de branche actives sont réutilisées et vous déterminez la fréquence à laquelle la clé de branche active est pivotée.

Les clés de branche ne sont pas utilisées pour chiffrer les clés de données en texte brut. Ils sont utilisés pour dériver les clés d'encapsulation uniques qui chiffrent les clés de données en texte brut. Le processus de dérivation de la clé d'encapsulation produit une clé d'encapsulation unique de 32 octets avec 28 octets aléatoires. Cela signifie qu'une clé de branche peut obtenir plus de 79 octillions, soit 2 96, clés d'encapsulation uniques avant que l'usure cryptographique ne se produise. Malgré ce très faible risque d'épuisement, il se peut que vous deviez effectuer une rotation de vos clés de succursale actives en raison de règles commerciales, contractuelles ou gouvernementales.

La version active de la clé de branche reste active jusqu'à ce que vous la fassiez pivoter. Les versions précédentes de la clé de branche active ne seront pas utilisées pour effectuer des opérations de chiffrement et ne peuvent pas être utilisées pour dériver de nouvelles clés d'encapsulation. Mais ils peuvent toujours être interrogés et fournir des clés d'encapsulation pour déchiffrer les clés de données qu'ils ont chiffrées lorsqu'ils sont actifs.

Utilisez le VersionKey service Key Store pour faire pivoter votre clé de branche active. Lorsque vous faites pivoter la clé de branche active, une nouvelle clé de branche est créée pour remplacer la version précédente. branch-key-idCela ne change pas lorsque vous faites pivoter la clé de branche active. Vous devez spécifier le code branch-key-id qui identifie la clé de branche active actuelle lorsque vous appelezVersionKey.

C# / .NET
keystore.VersionKey(new VersionKeyInput{BranchKeyIdentifier = branchKeyId});
Java
keystore.VersionKey( VersionKeyInput.builder() .branchKeyIdentifier("branch-key-id") .build() );

Utilisation du trousseau de clés hiérarchique dans les environnements multilocataires

Vous pouvez utiliser la hiérarchie des clés établie entre les clés de branche actives et leurs clés d'encapsulation dérivées pour prendre en charge les environnements multilocataires en créant une clé de branche pour chaque locataire de votre environnement. Le trousseau de clés hiérarchique chiffre ensuite toutes les données d'un locataire donné avec sa clé de branche distincte. Cela vous permet d'isoler les données des locataires par clé de succursale.

Chaque locataire possède sa propre clé de branche définie par une clé uniquebranch-key-id. Il ne peut y avoir qu'une seule version active de chaque version branch-key-id à la fois.

Avant de pouvoir initialiser votre trousseau de clés hiérarchique pour une utilisation par plusieurs locataires, vous devez créer une clé de branche pour chaque locataire et créer un fournisseur d'ID de clé de branche. Utilisez le fournisseur d'identifiant de clé de succursale pour créer un nom convivial branch-key-ids afin de permettre à un locataire de reconnaître plus facilement le nom correctbranch-key-id. Par exemple, le nom convivial vous permet de faire référence à une clé de branche comme tenant1 au lieu deb3f61619-4d35-48ad-a275-050f87e15122.

Pour les opérations de déchiffrement, vous pouvez soit configurer de manière statique un jeu de clés hiérarchique unique pour limiter le déchiffrement à un seul locataire, soit utiliser le fournisseur d'ID de clé de branche pour identifier le locataire responsable du déchiffrement d'un message.

Tout d'abord, suivez les étapes 1 et 2 des procédures relatives aux prérequis. Utilisez ensuite les procédures suivantes pour créer une clé de branche pour chaque locataire, créer un fournisseur d'ID de clé de branche et initialiser votre jeu de clés hiérarchique pour une utilisation par plusieurs locataires.

Étape 1 : créer une clé de branche pour chaque locataire de votre environnement

Appelez CreateKey pour chaque locataire.

L'opération suivante crée deux clés de branche à l'aide de la KMS clé que vous avez spécifiée lors de la création de votre service de magasin de clés, et ajoute les clés de branche à la table DynamoDB que vous avez créée pour servir de magasin de clés de branche. La même KMS clé doit protéger toutes les clés de branche.

C# / .NET
var branchKeyId1 = keystore.CreateKey(new CreateKeyInput()); var branchKeyId2 = keystore.CreateKey(new CreateKeyInput());
Java
CreateKeyOutput branchKeyId1 = keystore.CreateKey(CreateKeyInput.builder().build()); CreateKeyOutput branchKeyId2 = keystore.CreateKey(CreateKeyInput.builder().build());
Étape 2 : créer un fournisseur d'ID de clé de branche

L'exemple suivant crée un fournisseur d'ID de clé de branche.

C# / .NET
var branchKeySupplier = new ExampleBranchKeySupplier(branchKeyId1.BranchKeyIdentifier, branchKeyId2.BranchKeyIdentifier);
Java
IBranchKeyIdSupplier branchKeyIdSupplier = new ExampleBranchKeyIdSupplier( branchKeyId1.branchKeyIdentifier(), branchKeyId2.branchKeyIdentifier());
Étape 3 : Initialisez votre trousseau de clés hiérarchique avec le fournisseur d'ID de clé de branche

Pour initialiser le trousseau de clés hiérarchique, vous devez fournir les valeurs suivantes :

  • Un nom de magasin clé de succursale

  • Une limite de durée de vie du cache (TTL)

  • Un fournisseur d'identifiant de clé de succursale

  • (Facultatif) Un cache

    Si vous souhaitez personnaliser le type de cache ou le nombre d'entrées clés de branche pouvant être stockées dans le cache local, spécifiez le type de cache et la capacité d'entrée lorsque vous initialisez le trousseau de clés.

    Le type de cache définit le modèle de threading. Le trousseau de clés hiérarchique fournit trois types de cache compatibles avec les environnements multilocataires : Default,, MultiThreaded. StormTracking

    Si vous ne spécifiez pas de cache, le trousseau de clés hiérarchique utilise automatiquement le type de cache par défaut et définit la capacité d'entrée à 1 000.

    Default (Recommended)

    Pour la plupart des utilisateurs, le cache par défaut répond à leurs exigences en matière de threading. Le cache par défaut est conçu pour prendre en charge les environnements fortement multithread. Lorsqu'une entrée de matériel clé de branche expire, le cache par défaut empêche plusieurs threads d'appeler AWS KMS et Amazon DynamoDB en notifiant à un thread que l'entrée de matériel clé de branche va expirer 10 secondes à l'avance. Cela garantit qu'un seul thread envoie une demande AWS KMS pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un cache par défaut, spécifiez la valeur suivante :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    C#/. NET
    CacheType defaultCache = new CacheType { Default = new DefaultCache{EntryCapacity = 100} };
    Java
    .cache(CacheType.builder() .Default(DefaultCache.builder() .entryCapacity(100) .build())

    La valeur par défaut et StormTracking les caches prennent en charge le même modèle de thread, mais il suffit de spécifier la capacité d'entrée pour initialiser le trousseau de clés hiérarchique avec le cache par défaut. Pour des personnalisations de cache plus détaillées, utilisez le StormTracking cache.

    MultiThreaded

    Le MultiThreaded cache peut être utilisé en toute sécurité dans les environnements multithread, mais il ne fournit aucune fonctionnalité permettant de minimiser les appels Amazon AWS KMS DynamoDB. Par conséquent, lorsqu'une entrée de contenu clé de branche expire, tous les fils de discussion seront avertis en même temps. Cela peut entraîner plusieurs AWS KMS appels pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un MultiThreaded cache, spécifiez les valeurs suivantes :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    • Taille de la queue d'élagage d'entrée : définit le nombre d'entrées à élaguer si la capacité d'entrée est atteinte.

    C#/. NET
    CacheType multithreadedCache = new CacheType { MultiThreaded = new MultiThreadedCache { EntryCapacity = 100, EntryPruningTailSize = 1 } };
    Java
    .cache(CacheType.builder() .MultiThreaded(MultiThreadedCache.builder() .entryCapacity(100) .entryPruningTailSize(1) .build())
    StormTracking

    Le StormTracking cache est conçu pour prendre en charge les environnements fortement multithread. Lorsqu'une entrée de matériel de clé de branche expire, le StormTracking cache empêche plusieurs threads d'appeler AWS KMS et Amazon DynamoDB en notifiant à un thread que l'entrée de documents de clé de branche va expirer à l'avance. Cela garantit qu'un seul thread envoie une demande AWS KMS pour actualiser le cache.

    Pour initialiser votre trousseau de clés hiérarchique avec un StormTracking cache, spécifiez les valeurs suivantes :

    • Capacité d'entrée : limite le nombre d'entrées de matériaux clés de branche qui peuvent être stockées dans le cache local.

    • Taille de la queue d'élagage d'entrée : définit le nombre d'entrées de matériaux clés de branche à tailler à la fois.

      Valeur par défaut : 1 entrée

    • Période de grâce : définit le nombre de secondes avant l'expiration pendant lesquelles une tentative d'actualisation des documents clés de la branche est effectuée.

      Valeur par défaut : 10 secondes

    • Intervalle de grâce : définit le nombre de secondes entre les tentatives d'actualisation des éléments clés de la branche.

      Valeur par défaut : 1 seconde

    • Ventilateur : définit le nombre de tentatives simultanées qui peuvent être effectuées pour actualiser les documents clés de la branche.

      Valeur par défaut : 20 tentatives

    • In flight time to live (TTL) : définit le nombre de secondes avant l'expiration d'une tentative d'actualisation des éléments clés de la branche. Chaque fois que le cache revient NoSuchEntry en réponse à unGetCacheEntry, cette clé de branche est considérée comme étant en vol jusqu'à ce que la même clé soit écrite avec une PutCache entrée.

      Valeur par défaut : 20 secondes

    • Sommeil : définit le nombre de secondes pendant lesquelles un thread doit être mis en veille si le fanOut délai est dépassé.

      Valeur par défaut : 20 millisecondes

    C#/. NET
    CacheType stormTrackingCache = new CacheType { StormTracking = new StormTrackingCache { EntryCapacity = 100, EntryPruningTailSize = 1, FanOut = 20, GraceInterval = 1, GracePeriod = 10, InFlightTTL = 20, SleepMilli = 20 } };
    Java
    .cache(CacheType.builder() .MultiThreaded(MultiThreadedCache.builder() .entryCapacity(100) .entryPruningTailSize(1) .gracePeriod(10) .graceInterval(1) .fanOut(20) .inFlightTTL(20) .sleepMilli(20) .build())
  • (Facultatif) Une liste de jetons de subvention

    Si vous contrôlez l'accès à la KMS clé de votre trousseau hiérarchique avec des autorisations, vous devez fournir tous les jetons de subvention nécessaires lorsque vous initialisez le trousseau de clés.

L'exemple suivant initialise un jeu de clés hiérarchique avec le fournisseur d'ID de clé de branche créé à l'étape 2, une limite TLL de cache de 600 secondes et une capacité d'entrée de 1 000.

C# / .NET
var createKeyringInput = new CreateAwsKmsHierarchicalKeyringInput { KeyStore = keystore, BranchKeyIdSupplier = branchKeySupplier, Cache = new CacheType { Default = new DefaultCache{EntryCapacity = 1000} }, TtlSeconds = 600 }; var keyring = mpl.CreateAwsKmsHierarchicalKeyring(createKeyringInput);
Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder() .keyStore(branchKeyStoreName) .branchKeyIdSupplier(branchKeyIdSupplier) .ttlSeconds(600) .cache(CacheType.builder() //OPTIONAL .Default(DefaultCache.builder() .entryCapacity(100) .build()) .build(); final IKeyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
Étape 4 : Créez des noms conviviaux pour chaque clé de branche

L'exemple suivant crée des noms conviviaux pour les deux clés de branche créées à l'étape 1. AWS Encryption SDK Utilise des contextes de chiffrement pour associer le nom convivial que vous définissez au nom associébranch-key-id.

C# / .NET
// Create encryption contexts for the two branch keys created in Step 1 var encryptionContextA = new Dictionary<string, string>() { // We will encrypt with branchKeyTenantA {"tenant", "TenantA"}, {"encryption", "context"}, {"is not", "secret"}, {"but adds", "useful metadata"}, {"that can help you", "be confident that"}, {"the data you are handling", "is what you think it is"} }; var encryptionContextB = new Dictionary<string, string>() { // We will encrypt with branchKeyTenantB {"tenant", "TenantB"}, {"encryption", "context"}, {"is not", "secret"}, {"but adds", "useful metadata"}, {"that can help you", "be confident that"}, {"the data you are handling", "is what you think it is"} }; // Instantiate the AWS Encryption SDK var esdk = new ESDK(new AwsEncryptionSdkConfig()); var encryptInputA = new EncryptInput { Plaintext = plaintext, Keyring = keyring, // Encrypt with branchKeyId1 EncryptionContext = encryptionContextA }; var encryptInputB = new EncryptInput { Plaintext = plaintext, Keyring = keyring, // Encrypt with branchKeyId2 EncryptionContext = encryptionContextB }; var encryptOutput = esdk.Encrypt(encryptInputA); encryptOutput = esdk.Encrypt(encryptInputB); // Use the encryption contexts to define friendly names for each branch key public class ExampleBranchKeySupplier : IBranchKeyIdSupplier { private string branchKeyTenantA; private string branchKeyTenantB; public ExampleBranchKeySupplier(string branchKeyTenantA, string branchKeyTenantB) { this.branchKeyTenantA = branchKeyTenantA; this.branchKeyTenantB = branchKeyTenantB; } public GetBranchKeyIdOutput GetBranchKeyId(GetBranchKeyIdInput input) { Dictionary<string, string> encryptionContext = input.EncryptionContext; if (!encryptionContext.ContainsKey("tenant")) { throw new Exception("EncryptionContext invalid, does not contain expected tenant key value pair."); } string tenant = encryptionContext["tenant"]; string branchkeyId; if (tenant.Equals("TenantA")) { GetBranchKeyIdOutput output = new GetBranchKeyIdOutput(); output.BranchKeyId = branchKeyTenantA; return output; } else if (tenant.Equals("TenantB")) { GetBranchKeyIdOutput output = new GetBranchKeyIdOutput(); output.BranchKeyId = branchKeyTenantB; return output; } else { throw new Exception("Item does not have a valid tenantID."); } } }
Java
// Create encryption context for branchKeyTenantA Map<String, String> encryptionContextA = new HashMap<>(); encryptionContextA.put("tenant", "TenantA"); encryptionContextA.put("encryption", "context"); encryptionContextA.put("is not", "secret"); encryptionContextA.put("but adds", "useful metadata"); encryptionContextA.put("that can help you", "be confident that"); encryptionContextA.put("the data you are handling", "is what you think it is"); // Create encryption context for branchKeyTenantB Map<String, String> encryptionContextB = new HashMap<>(); encryptionContextB.put("tenant", "TenantB"); encryptionContextB.put("encryption", "context"); encryptionContextB.put("is not", "secret"); encryptionContextB.put("but adds", "useful metadata"); encryptionContextB.put("that can help you", "be confident that"); encryptionContextB.put("the data you are handling", "is what you think it is"); // Instantiate the AWS Encryption SDK final AwsCrypto crypto = AwsCrypto.builder().build(); final CryptoResult<byte[], ?> encryptResultA = crypto.encryptData(keyring, plaintext, encryptionContextA); final CryptoResult<byte[], ?> encryptResultB = crypto.encryptData(keyring, plaintext, encryptionContextB); // Use the encryption contexts to define friendly names for each branch key public class ExampleBranchKeyIdSupplier implements IBranchKeyIdSupplier { private static String branchKeyIdForTenantA; private static String branchKeyIdForTenantB; public ExampleBranchKeyIdSupplier(String tenant1Id, String tenant2Id) { this.branchKeyIdForTenantA = tenant1Id; this.branchKeyIdForTenantB = tenant2Id; } @Override public GetBranchKeyIdOutput GetBranchKeyId(GetBranchKeyIdInput input) { Map<String, String> encryptionContext = input.encryptionContext(); if (!encryptionContext.containsKey("tenant")) { throw new IllegalArgumentException("EncryptionContext invalid, does not contain expected tenant key value pair."); } String tenantKeyId = encryptionContext.get("tenant"); String branchKeyId; if (tenantKeyId.equals("TenantA")) { branchKeyId = branchKeyIdForTenantA; } else if (tenantKeyId.equals("TenantB")) { branchKeyId = branchKeyIdForTenantB; } else { throw new IllegalArgumentException("Item does not contain valid tenant ID"); } return GetBranchKeyIdOutput.builder().branchKeyId(branchKeyId).build(); } }