AWS KMS Portachiavi gerarchici - AWS SDK per la crittografia del database

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

AWS KMS Portachiavi gerarchici

La nostra libreria di crittografia lato client è stata rinominata Database Encryption SDK. AWS Questa guida per sviluppatori fornisce ancora informazioni sul DynamoDB Encryption Client.
Nota

A partire dal 24 luglio 2023, le chiavi di filiale create durante l'anteprima per sviluppatori non sono supportate. Crea nuove chiavi di filiale per continuare a utilizzare l'archivio di chiavi di filiale creato durante l'anteprima per sviluppatori.

Con il portachiavi AWS KMS Hierarchical, puoi proteggere i tuoi materiali crittografici con una chiave KMS a crittografia simmetrica senza chiamare AWS KMS ogni volta che crittografi o decrittografi un record. È una buona scelta per le applicazioni che devono ridurre al minimo le chiamate e le applicazioni che possono riutilizzare alcuni materiali crittografici AWS KMS senza violare i requisiti di sicurezza.

Il portachiavi Hierarchical è una soluzione di memorizzazione nella cache dei materiali crittografici che riduce il numero di AWS KMS chiamate utilizzando chiavi branch AWS KMS protette persistenti in una tabella Amazon DynamoDB e quindi memorizzando nella cache locale i materiali chiave delle branch utilizzati nelle operazioni di crittografia e decrittografia. La tabella DynamoDB funge da archivio delle chiavi di filiale che gestisce e protegge le chiavi delle filiali. Memorizza la chiave di ramo attiva e tutte le versioni precedenti della chiave di ramo. La chiave di ramo attiva è la versione più recente della chiave di filiale. Il portachiavi Hierarchical utilizza una chiave dati unica per crittografare ogni campo e crittografa ogni chiave di dati con una chiave di wrapping unica derivata dalla chiave branch attiva. Il portachiavi Hierarchical dipende dalla gerarchia stabilita tra le chiavi branch attive e le relative chiavi di wrapping derivate.

Il portachiavi Hierarchical utilizza in genere ogni versione della chiave branch per soddisfare più richieste. Tuttavia, puoi controllare la misura in cui le chiavi di ramo attive vengono riutilizzate e determinare la frequenza con cui la chiave di ramo attiva viene ruotata. La versione attiva della chiave di ramo rimane attiva finché non viene ruotata. Le versioni precedenti della chiave branch attiva non verranno utilizzate per eseguire operazioni di crittografia, ma potranno comunque essere interrogate e utilizzate nelle operazioni di decrittografia.

Quando si crea un'istanza del portachiavi Hierarchical, viene creata una cache locale. Si specifica un limite di cache che definisce la quantità massima di tempo in cui i materiali chiave del branch vengono archiviati nella cache locale prima che scadano e vengano rimossi dalla cache. Il portachiavi Hierarchical effettua una AWS KMS chiamata per decrittografare la chiave del ramo e assemblare i materiali delle chiavi del ramo la prima volta che a viene specificato in un'operazione. branch-key-id I materiali delle chiavi di filiale vengono quindi archiviati nella cache locale e riutilizzati per tutte le operazioni di crittografia e decrittografia che lo specificano fino alla scadenza del limite di cache. branch-key-id La memorizzazione dei materiali chiave della filiale nella cache locale riduce le chiamate. AWS KMS Ad esempio, si consideri un limite di cache di 15 minuti. Se si eseguono 10.000 operazioni di crittografia entro tale limite di cache, il AWS KMS portachiavi tradizionale dovrebbe effettuare 10.000 AWS KMS chiamate per soddisfare 10.000 operazioni di crittografia. Se ne hai uno attivobranch-key-id, il portachiavi Hierarchical deve effettuare solo una AWS KMS chiamata per soddisfare 10.000 operazioni di crittografia.

La cache locale è composta da due partizioni, una per le operazioni di crittografia e una seconda per le operazioni di decrittografia. La partizione di crittografia memorizza i materiali delle chiavi di branch assemblati dalla chiave branch attiva e li riutilizza per tutte le operazioni di crittografia fino alla scadenza del limite della cache. La partizione di decrittografia memorizza i materiali delle chiavi di filiale assemblati per altre versioni di chiavi di filiale identificate nelle operazioni di decrittografia. La partizione di decrittografia può memorizzare più versioni di materiali chiave di filiale attivi contemporaneamente. Quando è configurata per utilizzare un fornitore di ID di chiavi di filiale per un database multitenant, la partizione encrypt può anche archiviare più versioni di materiali relativi alle chiavi di filiale contemporaneamente. Per ulteriori informazioni, consulta Utilizzo del portachiavi Hierarchical con database multitenant.

Nota

Tutte le menzioni del portachiavi gerarchico nel Database Encryption SDK si riferiscono al AWS portachiavi gerarchico. AWS KMS

Come funziona

Le seguenti procedure dettagliate descrivono come il portachiavi Hierarchical assembla i materiali di crittografia e decrittografia e le diverse chiamate che il portachiavi effettua per le operazioni di crittografia e decrittografia. Per i dettagli tecnici sulla derivazione delle chiavi di wrapping e sui processi di crittografia delle chiavi di dati in chiaro, consulta Dettagli tecnici del portachiavi gerarchico.AWS KMS

Crittografa e firma

La procedura dettagliata seguente descrive come il portachiavi Hierarchical assembla i materiali di crittografia e ricava una chiave di avvolgimento univoca.

  1. Il metodo di crittografia richiede al portachiavi Hierarchical i materiali di crittografia. Il portachiavi genera una chiave di dati in testo semplice, quindi verifica se nella cache locale sono presenti materiali branch validi per generare la chiave di wrapping. Se sono presenti materiali validi per le chiavi di filiale, il portachiavi passa alla Fase 5.

  2. Se non ci sono materiali validi per le chiavi di filiale, il portachiavi Hierarchical interroga l'archivio delle chiavi di filiale per trovare la chiave di filiale attiva.

    1. L'archivio delle chiavi di filiale chiama AWS KMS per decrittografare la chiave di ramo attiva e restituisce la chiave di ramo attiva in testo semplice. I dati che identificano la chiave di ramo attiva vengono serializzati per fornire dati autenticati aggiuntivi (AAD) nella chiamata di decrittografia a. AWS KMS

    2. L'archivio delle chiavi di filiale restituisce la chiave di ramo in testo semplice e i dati che la identificano, ad esempio la versione della chiave di filiale.

  3. Il portachiavi Hierarchical assembla i materiali chiave del ramo (la chiave di ramo in testo semplice e la versione della chiave di ramo) e ne archivia una copia nella cache locale.

  4. Il portachiavi Hierarchical ricava una chiave di avvolgimento unica dalla chiave branch in testo semplice e un sale casuale a 16 byte. Utilizza la chiave di wrapping derivata per crittografare una copia della chiave di dati in testo non crittografato.

Il metodo di crittografia utilizza i materiali di crittografia per crittografare e firmare il record. Per ulteriori informazioni su come i record vengono crittografati e firmati nel AWS Database Encryption SDK, consulta Encrypt and sign.

Decrittografa e verifica

La procedura dettagliata seguente descrive come il portachiavi gerarchico assembla i materiali di decrittografia e decrittografa la chiave di dati crittografata.

  1. Il metodo di decrittografia identifica la chiave di dati crittografata dal campo di descrizione del materiale del record crittografato e la passa al portachiavi gerarchico.

  2. Il portachiavi Hierarchical deserializza i dati che identificano la chiave dati crittografata, inclusa la versione della chiave branch, il sale da 16 byte e altre informazioni che descrivono come è stata crittografata la chiave dati.

    Per ulteriori informazioni, consulta AWS KMSDettagli tecnici del portachiavi gerarchico.

  3. Il portachiavi Hierarchical verifica se nella cache locale sono presenti materiali chiave di filiale validi che corrispondono alla versione della chiave di filiale identificata nel passaggio 2. Se sono presenti materiali validi per le chiavi di filiale, il portachiavi passa alla Fase 6.

  4. Se non ci sono materiali validi per le chiavi di filiale, il portachiavi Hierarchical interroga l'archivio delle chiavi di filiale per trovare la chiave di filiale che corrisponde alla versione della chiave di filiale identificata nello Step 2.

    1. L'archivio delle chiavi di filiale chiama AWS KMS per decrittografare la chiave di ramo e restituisce la chiave di ramo attiva in testo semplice. I dati che identificano la chiave di ramo attiva vengono serializzati per fornire dati autenticati aggiuntivi (AAD) nella chiamata di decrittografia a. AWS KMS

    2. L'archivio delle chiavi di filiale restituisce la chiave di ramo in testo semplice e i dati che la identificano, ad esempio la versione della chiave di filiale.

  5. Il portachiavi Hierarchical assembla i materiali chiave del ramo (la chiave di ramo in testo semplice e la versione della chiave di ramo) e ne archivia una copia nella cache locale.

  6. Il portachiavi Hierarchical utilizza i materiali delle chiavi branch assemblate e il sale da 16 byte identificato nella fase 2 per riprodurre la chiave di avvolgimento univoca che crittografava la chiave dati.

  7. Il portachiavi Hierarchical utilizza la chiave di wrapping riprodotta per decrittografare la chiave dati e restituisce la chiave dati in testo semplice.

Il metodo di decrittografia utilizza i materiali di decrittografia e la chiave di dati in testo semplice per decrittografare e verificare il record. Per ulteriori informazioni su come i record vengono decrittografati e verificati nel Database Encryption SDK, consulta Decriptare e verificare. AWS

Prerequisiti

Il AWS Database Encryption SDK non richiede Account AWS e non dipende da nessuno. Servizio AWS Tuttavia, il portachiavi gerarchico dipende da Amazon AWS KMS DynamoDB.

Per utilizzare un portachiavi gerarchico, è necessaria una crittografia simmetrica con autorizzazioni KMS:Decrypt. AWS KMS key È inoltre possibile utilizzare una chiave multiregionale con crittografia simmetrica. Per informazioni dettagliate sulle autorizzazioni per AWS KMS keys, consulta Autenticazione e controllo degli accessi nella Guida per gli sviluppatori.AWS Key Management Service

Prima di poter creare e utilizzare un portachiavi gerarchico, è necessario creare l'archivio delle chiavi della filiale e compilarlo con la prima chiave di filiale attiva.

Fase 1: Configurare un nuovo servizio di archiviazione delle chiavi

Il servizio di archiviazione delle chiavi offre diverse operazioni, ad esempio CreateKeyStore eCreateKey, per aiutarti a assemblare i prerequisiti gerarchici del portachiavi e a gestire l'archivio delle chiavi della filiale.

L'esempio seguente crea un servizio di archiviazione delle chiavi. È necessario specificare un nome di tabella DynamoDB che funga da nome dell'archivio chiavi della filiale, un nome logico per l'archivio chiavi della filiale e l'ARN della chiave KMS che identifica la chiave KMS che proteggerà le chiavi della filiale.

Il nome dell'archivio di chiavi logiche è associato crittograficamente a tutti i dati memorizzati nella tabella per semplificare le operazioni di ripristino di DynamoDB. Il nome dell'archivio di chiavi logiche può essere lo stesso del nome della tabella DynamoDB, ma non è necessario. Consigliamo vivamente di specificare il nome della tabella DynamoDB come nome della tabella logica quando si configura per la prima volta il servizio di archiviazione delle chiavi. È necessario specificare sempre lo stesso nome di tabella logica. Nel caso in cui il nome dell'archivio chiavi della filiale cambi dopo il ripristino della tabella DynamoDB da un backup, il nome dell'archivio di chiavi logico viene mappato al nome della tabella DynamoDB specificato per garantire che il portachiavi Hierarchical possa ancora accedere all'archivio delle chiavi della filiale.

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();
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);
Fase 2: Chiama per creare un archivio di chiavi della filiale CreateKeyStore

La seguente operazione crea l'archivio delle chiavi della filiale che persisterà e proteggerà le chiavi della filiale.

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

L'CreateKeyStoreoperazione crea una tabella DynamoDB con il nome della tabella specificato nel passaggio 1 e i seguenti valori obbligatori.

Chiave di partizione Chiave di ordinamento
Tabella di base branch-key-id type
Nota

È possibile creare manualmente la tabella DynamoDB che funge da archivio delle chiavi della filiale anziché utilizzare l'operazione. CreateKeyStore Se scegli di creare manualmente l'archivio delle chiavi di filiale, devi specificare i seguenti valori di stringa per le chiavi di partizione e ordinamento:

  • Chiave di partizione: branch-key-id

  • Chiave di ordinamento: type

Passaggio 3: Chiama CreateKey per creare una nuova chiave di ramo attiva

La seguente operazione crea una nuova chiave di ramo attiva utilizzando la chiave KMS specificata nel passaggio 1 e aggiunge la chiave di ramo attiva alla tabella DynamoDB creata nel passaggio 2.

Quando si chiamaCreateKey, è possibile scegliere di specificare i seguenti valori opzionali.

  • branchKeyIdentifier: definisce una personalizzazionebranch-key-id.

    Per creare una personalizzazionebranch-key-id, è necessario includere anche un contesto di crittografia aggiuntivo con il encryptionContext parametro.

  • encryptionContext: definisce un set opzionale di coppie chiave-valore non segrete che fornisce dati autenticati aggiuntivi (AAD) nel contesto di crittografia incluso nella chiamata kms:. GenerateDataKeyWithoutPlaintext

    Questo contesto di crittografia aggiuntivo viene visualizzato con il prefisso. aws-crypto-ec:

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();
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 });

Innanzitutto, l'CreateKeyoperazione genera i seguenti valori.

Quindi, l'CreateKeyoperazione chiama kms: GenerateDataKeyWithoutPlaintext utilizzando la seguente richiesta.

{ "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" }
Nota

L'CreateKeyoperazione crea una chiave branch attiva e una chiave beacon, anche se il database non è stato configurato per la crittografia ricercabile. Entrambe le chiavi sono archiviate nell'archivio delle chiavi della filiale. Per ulteriori informazioni, consulta Utilizzo del portachiavi gerarchico per la crittografia ricercabile.

Successivamente, l'CreateKeyoperazione chiama kms: ReEncrypt per creare un record attivo per la chiave branch aggiornando il contesto di crittografia.

Infine, l'CreateKeyoperazione chiama ddb: TransactWriteItems per scrivere un nuovo elemento che mantenga la chiave di ramo nella tabella creata nel passaggio 2. L'elemento ha i seguenti attributi.

{ "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" }

Crea un portachiavi gerarchico

Per inizializzare il portachiavi gerarchico, è necessario fornire i seguenti valori:

  • Il nome di un archivio di chiavi della filiale

    Il nome della tabella DynamoDB che hai creato per fungere da archivio delle chiavi della filiale.

  • Un limite di durata della cache (TTL)

    La quantità di tempo, in secondi, durante la quale una chiave di filiale deve essere inserita nella cache locale può essere utilizzata prima della scadenza. Il limite di cache TTL determina la frequenza con cui il client chiama AWS KMS per autorizzare l'uso delle chiavi della filiale. Questo valore deve essere maggiore di zero. Quando il limite di cache TTL scade, la voce viene rimossa dalla cache locale.

  • Un identificatore di chiave di filiale

    Il branch-key-id che identifica la chiave di filiale attiva nell'archivio delle chiavi della filiale.

    Nota

    Per inizializzare il portachiavi Hierarchical per l'uso multitenant, è necessario specificare un fornitore di ID di chiavi di filiale anziché un. branch-key-id Per ulteriori informazioni, consulta Utilizzo del portachiavi Hierarchical con database multitenant.

  • (Facoltativo) Un elenco di token di concessione

    Se controlli l'accesso alla chiave KMS nel tuo portachiavi gerarchico con le concessioni, devi fornire tutti i token di concessione necessari quando inizializzi il portachiavi.

Gli esempi seguenti mostrano come inizializzare un portachiavi gerarchico con il client AWS Database Encryption SDK per DynamoDB. L'esempio seguente specifica un limite di cache TTL di 600 secondi.

Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder() .keyStore(branchKeyStoreName) .branchKeyId(branch-key-id) .ttlSeconds(600) .build(); final Keyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var keyringInput = new CreateAwsKmsHierarchicalKeyringInput { KeyStore = keystore, BranchKeyIdSupplier = branchKeyIdSupplier, TtlSeconds = 600 }; var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);

Ruota la chiave branch attiva

Può esserci una sola versione attiva per ogni chiave di ramo alla volta. Il portachiavi Hierarchical utilizza in genere ogni versione di chiave branch attiva per soddisfare più richieste. Ma sei tu a controllare la misura in cui le chiavi branch attive vengono riutilizzate e a determinare la frequenza con cui la chiave branch attiva viene ruotata.

Le chiavi branch non vengono utilizzate per crittografare le chiavi di dati in testo semplice. Vengono utilizzate per derivare le chiavi di wrapping uniche che crittografano le chiavi di dati in testo semplice. Il processo di derivazione della chiave di wrapping produce una chiave di wrapping unica da 32 byte con 28 byte di casualità. Ciò significa che una chiave branch può derivare più di 79 ottilioni, o 2 96, chiavi di wrapping uniche prima che si verifichi l'usura crittografica. Nonostante questo rischio di esaurimento molto basso, potrebbe essere necessario ruotare le chiavi di filiale attive a causa di norme aziendali o contrattuali o normative governative.

La versione attiva della chiave di filiale rimane attiva finché non viene ruotata. Le versioni precedenti della chiave branch attiva non verranno utilizzate per eseguire operazioni di crittografia e non possono essere utilizzate per derivare nuove chiavi di wrapping. Tuttavia, possono comunque essere interrogate e fornire chiavi di wrapping per decrittografare le chiavi di dati che hanno crittografato mentre erano attive.

Utilizza il servizio di archiviazione delle chiavi per ruotare VersionKey la chiave branch attiva. Quando si ruota la chiave di ramo attiva, viene creata una nuova chiave di ramo per sostituire la versione precedente. Non branch-key-id cambia quando si ruota la chiave di ramo attiva. È necessario specificare la chiave branch-key-id che identifica la chiave di ramo attiva corrente quando si chiama. VersionKey

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

Utilizzo del portachiavi Hierarchical con database multitenant

È possibile utilizzare la gerarchia di chiavi stabilita tra le chiavi branch attive e le relative chiavi di wrapping derivate per supportare i database multitenant creando una chiave branch per ogni tenant del database. Il portachiavi Hierarchical crittografa e firma quindi tutti i dati di un determinato tenant con la relativa chiave branch distinta. Ciò consente di archiviare i dati di più tenant in un unico database e di isolare i dati del tenant per chiave di filiale.

Ogni tenant ha la propria chiave di filiale definita da un'unica. branch-key-id Può esserci solo una versione attiva di ciascuno branch-key-id alla volta.

Branch Key ID (fornitore).

Prima di poter inizializzare il portachiavi gerarchico per l'uso multitenant, è necessario creare una chiave di filiale per ogni tenant e creare un fornitore di ID di chiave di filiale. Il fornitore dell'ID della chiave di filiale utilizza i campi memorizzati nel contesto di crittografia per determinare quale chiave di filiale del tenant è necessaria per decrittografare un record. Per impostazione predefinita, nel contesto di crittografia sono incluse solo le chiavi di partizione e ordinamento. Tuttavia, è possibile utilizzare l'azione SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT crittografica per includere campi aggiuntivi nel contesto di crittografia.

Nota

Per utilizzare l'azione SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT crittografica, è necessario utilizzare la versione 3.3 o successiva del AWS Database Encryption SDK. Distribuisci la nuova versione a tutti i lettori prima di aggiornare il modello di dati per includere. SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT

Puoi utilizzare il fornitore di codici identificativi della filiale per creare un nome branch-key-ids descrittivo per facilitare il riconoscimento di quello corretto branch-key-id per un tenant. Ad esempio, il nome descrittivo consente di fare riferimento a una chiave di filiale come tenant1 invece dib3f61619-4d35-48ad-a275-050f87e15122.

Per le operazioni di decrittografia, è possibile configurare staticamente un singolo portachiavi gerarchico per limitare la decrittografia a un singolo tenant, oppure è possibile utilizzare il fornitore di ID della chiave di filiale per identificare quale tenant è responsabile della decrittografia di un record.

Per prima cosa, segui i passaggi 1 e 2 delle procedure relative ai prerequisiti. Quindi, utilizzate le seguenti procedure per creare una chiave di filiale per ogni tenant, creare un fornitore di ID di chiavi di filiale e inizializzare il portachiavi Hierarchical per l'uso multitenant.

Passaggio 1: crea una chiave di filiale per ogni tenant nel database

Chiama CreateKey ogni inquilino del tuo database.

La seguente operazione crea due chiavi di ramo utilizzando la chiave KMS specificata durante la creazione del servizio di archivio chiavi e aggiunge le chiavi di ramo alla tabella DynamoDB creata per fungere da archivio chiavi di filiale. La stessa chiave KMS deve proteggere tutte le chiavi di filiale.

Java
CreateKeyOutput branchKeyId1 = keystore.CreateKey(CreateKeyInput.builder().build()); CreateKeyOutput branchKeyId2 = keystore.CreateKey(CreateKeyInput.builder().build());
C# / .NET
var branchKeyId1 = keystore.CreateKey(new CreateKeyInput()); var branchKeyId2 = keystore.CreateKey(new CreateKeyInput());
Fase 2: Creare un fornitore di chiavi di filiale (ID)

L'esempio seguente crea nomi descrittivi per le due chiavi di ramo create nel passaggio 1 e chiama CreateDynamoDbEncryptionBranchKeyIdSupplier a creare un fornitore di ID di chiavi di filiale con il client AWS Database Encryption SDK per DynamoDB.

Java
// Create friendly names for each branch-key-id class ExampleBranchKeyIdSupplier implements IDynamoDbKeyBranchKeyIdSupplier { private static String branchKeyIdForTenant1; private static String branchKeyIdForTenant2; public ExampleBranchKeyIdSupplier(String tenant1Id, String tenant2Id) { this.branchKeyIdForTenant1 = tenant1Id; this.branchKeyIdForTenant2 = tenant2Id; } // Create the branch key ID supplier final DynamoDbEncryption ddbEnc = DynamoDbEncryption.builder() .DynamoDbEncryptionConfig(DynamoDbEncryptionConfig.builder().build()) .build(); final BranchKeyIdSupplier branchKeyIdSupplier = ddbEnc.CreateDynamoDbEncryptionBranchKeyIdSupplier( CreateDynamoDbEncryptionBranchKeyIdSupplierInput.builder() .ddbKeyBranchKeyIdSupplier(new ExampleBranchKeyIdSupplier(branch-key-ID-tenant1, branch-key-ID-tenant2)) .build()).branchKeyIdSupplier();
C# / .NET
// Create friendly names for each branch-key-id class ExampleBranchKeyIdSupplier : DynamoDbKeyBranchKeyIdSupplierBase { private String _branchKeyIdForTenant1; private String _branchKeyIdForTenant2; public ExampleBranchKeyIdSupplier(String tenant1Id, String tenant2Id) { this._branchKeyIdForTenant1 = tenant1Id; this._branchKeyIdForTenant2 = tenant2Id; } // Create the branch key ID supplier var ddbEnc = new DynamoDbEncryption(new DynamoDbEncryptionConfig()); var branchKeyIdSupplier = ddbEnc.CreateDynamoDbEncryptionBranchKeyIdSupplier( new CreateDynamoDbEncryptionBranchKeyIdSupplierInput { DdbKeyBranchKeyIdSupplier = new ExampleBranchKeyIdSupplier(branch-key-ID-tenant1, branch-key-ID-tenant2) }).BranchKeyIdSupplier;
Fase 3: inizializza il portachiavi Hierarchical con il branch key ID (fornitore)

Per inizializzare il portachiavi gerarchico è necessario fornire i seguenti valori:

  • Il nome di un archivio di chiavi della filiale

  • Un limite di durata della cache (TTL)

  • Un fornitore di codici identificativi per filiali

  • (Facoltativo) Una cache

    Se desideri personalizzare il tipo di cache o il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale, specifica il tipo di cache e la capacità di accesso quando inizializzi il portachiavi.

    Il tipo di cache definisce il modello di threading. Il portachiavi Hierarchical fornisce tre tipi di cache che supportano database multitenant: Default,,. MultiThreaded StormTracking

    Se non si specifica una cache, il portachiavi Hierarchical utilizza automaticamente il tipo di cache predefinito e imposta la capacità di ingresso su 1000.

    Default (Recommended)

    Per la maggior parte degli utenti, la cache predefinita soddisfa i requisiti di threading. La cache predefinita è progettata per supportare ambienti con molti multithread. Quando una voce relativa ai materiali delle chiavi di branch scade, la cache predefinita impedisce la chiamata di più thread AWS KMS notificando a un thread che la voce relativa ai materiali della chiave di branch sta per scadere con 10 secondi di anticipo. Ciò garantisce che solo un thread invii una richiesta di aggiornamento della cache AWS KMS .

    Per inizializzare il tuo portachiavi gerarchico con una cache predefinita, specifica il seguente valore:

    • Capacità di accesso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

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

    Il valore predefinito e le StormTracking cache supportano lo stesso modello di threading, ma è sufficiente specificare la capacità di ingresso per inizializzare il portachiavi gerarchico con la cache predefinita. Per personalizzazioni più granulari della cache, usa la cache. StormTracking

    MultiThreaded

    La MultiThreaded cache è sicura da usare in ambienti multithread, ma non fornisce alcuna funzionalità per ridurre al minimo AWS KMS le chiamate Amazon DynamoDB. Di conseguenza, quando scade l'immissione di materiali chiave in una filiale, tutti i thread verranno avvisati contemporaneamente. Ciò può comportare più AWS KMS chiamate per aggiornare la cache.

    Per inizializzare il tuo portachiavi Hierarchical con una MultiThreaded cache, specifica i seguenti valori:

    • Capacità di ingresso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

    • Entry Poting Tail Size: definisce il numero di elementi da potare se viene raggiunta la capacità di ingresso.

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

    La StormTracking cache è progettata per supportare ambienti fortemente multithread. Quando una voce relativa ai materiali della chiave di filiale scade, la StormTracking cache impedisce la chiamata di più thread AWS KMS notificando in anticipo a un thread che la voce relativa ai materiali chiave della branch sta per scadere. Ciò garantisce che solo un thread invii una richiesta di aggiornamento della cache AWS KMS .

    Per inizializzare il tuo portachiavi Hierarchical con una StormTracking cache, specifica i seguenti valori:

    • Capacità di ingresso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

    • Dimensione della coda di potatura d'ingresso: definisce il numero di materiali chiave del ramo da potare alla volta.

      Valore predefinito: 1 voce

    • Periodo di tolleranza: definisce il numero di secondi prima della scadenza in cui viene effettuato un tentativo di aggiornare i materiali chiave della filiale.

      Valore predefinito: 10 secondi

    • Intervallo di grazia: definisce il numero di secondi tra i tentativi di aggiornamento dei materiali chiave del ramo.

      Valore predefinito: 1 secondo

    • Fan out: definisce il numero di tentativi simultanei che è possibile effettuare per aggiornare i materiali chiave della filiale.

      Valore predefinito: 20 tentativi

    • In flight time to live (TTL): definisce il numero di secondi che mancano al timeout di un tentativo di aggiornamento dei materiali chiave della filiale. Ogni volta che la cache ritorna NoSuchEntry in risposta a unaGetCacheEntry, quella chiave di ramo viene considerata in esecuzione finché la stessa chiave non viene scritta con una PutCache voce.

      Valore predefinito: 20 secondi

    • Sospensione: definisce il numero di secondi in cui un thread deve dormire se fanOut viene superato il limite.

      Valore predefinito: 20 millisecondi

    Java
    .cache(CacheType.builder() .StormTracking(StormTrackingCache.builder() .entryCapacity(100) .entryPruningTailSize(1) .gracePeriod(10) .graceInterval(1) .fanOut(20) .inFlightTTL(20) .sleepMilli(20) .build())
    C#/.NET
    CacheType stormTrackingCache = new CacheType { StormTracking = new StormTrackingCache { EntryCapacity = 100, EntryPruningTailSize = 1, FanOut = 20, GraceInterval = 1, GracePeriod = 10, InFlightTTL = 20, SleepMilli = 20 } };
  • (Facoltativo) Un elenco di token di concessione

    Se controlli l'accesso alla chiave KMS nel tuo portachiavi gerarchico con le concessioni, devi fornire tutti i token di concessione necessari quando inizializzi il portachiavi.

Gli esempi seguenti inizializzano un portachiavi Hierarchical con il branch key ID supplier creato nel passaggio 2, un TLL limite di cache di 600 secondi e una dimensione massima della cache di 1000. Questo esempio inizializza un portachiavi Hierarchical con il client Database AWS Encryption SDK per DynamoDB.

Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsHierarchicalKeyringInput keyringInput = CreateAwsKmsHierarchicalKeyringInput.builder() .keyStore(keystore) .branchKeyIdSupplier(branchKeyIdSupplier) .ttlSeconds(600) .cache(CacheType.builder() //OPTIONAL .Default(DefaultCache.builder() .entryCapacity(100) .build()) .build(); final Keyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var keyringInput = new CreateAwsKmsHierarchicalKeyringInput { KeyStore = keystore, BranchKeyIdSupplier = branchKeyIdSupplier, TtlSeconds = 600, Cache = new CacheType { Default = new DefaultCache { EntryCapacity = 100 } } }; var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);

Utilizzo del portachiavi Hierarchical per una crittografia ricercabile

La crittografia ricercabile consente di cercare record crittografati senza decrittografare l'intero database. Ciò si ottiene indicizzando il valore in chiaro di un campo crittografato con un beacon. Per implementare la crittografia ricercabile, è necessario utilizzare un portachiavi gerarchico.

L'CreateKeyoperazione di archiviazione delle chiavi genera sia una chiave branch che una chiave beacon. La chiave branch viene utilizzata nelle operazioni di crittografia e decrittografia dei record. La chiave beacon viene utilizzata per generare beacon.

La chiave branch e la chiave beacon sono protette dallo stesso AWS KMS key che hai specificato durante la creazione del servizio di archiviazione delle chiavi. Dopo che l'CreateKeyoperazione chiama AWS KMS per generare la chiave branch, chiama kms: GenerateDataKeyWithoutPlaintext una seconda volta per generare la chiave beacon utilizzando la seguente richiesta.

{ "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 }, "KeyId": "the KMS key ARN", "NumberOfBytes": "32" }

Dopo aver generato entrambe le chiavi, l'CreateKeyoperazione chiama ddb: TransactWriteItems per scrivere due nuovi elementi che mantengano la chiave branch e la chiave beacon nell'archivio delle chiavi della filiale.

Quando configuri un beacon standard, il AWS Database Encryption SDK interroga l'archivio delle chiavi del branch per cercare la chiave beacon. Quindi, utilizza una funzione di derivazione delle extract-and-expand chiavi basata su HMAC (HKDF) per combinare la chiave beacon con il nome del beacon standard per creare la chiave HMAC per un determinato beacon.

A differenza delle chiavi branch, esiste una sola versione di chiave beacon per ogni filiale. branch-key-id La chiave beacon non viene mai ruotata.

Definizione della fonte della chiave del beacon

Quando si definisce la versione beacon per i beacon standard e compositi, è necessario identificare la chiave beacon e definire un TTL (cache limit time to live) per i materiali chiave del beacon. I materiali delle chiavi beacon vengono archiviati in una cache locale separata dalle chiavi branch. Il seguente frammento mostra come definire un database single-tenant. keySource Identifica la tua chiave beacon in base alla quale è associata. branch-key-id

Java
keySource(BeaconKeySource.builder() .single(SingleKeyStore.builder() .keyId(branch-key-id) .cacheTTL(6000) .build()) .build())
C# / .NET
KeySource = new BeaconKeySource { Single = new SingleKeyStore { KeyId = branch-key-id, CacheTTL = 6000 } }
Definizione della fonte del beacon in un database multitenant

Se si dispone di un database multitenant, è necessario specificare i seguenti valori durante la configurazione di. keySource

  • keyFieldName

    Definisce il nome del campo che memorizza la chiave beacon branch-key-id associata alla chiave beacon utilizzata per generare i beacon per un determinato tenant. keyFieldNamePuò essere una stringa qualsiasi, ma deve essere univoca per tutti gli altri campi del database. Quando si scrivono nuovi record nel database, la chiave branch-key-id che identifica la chiave beacon utilizzata per generare i beacon per quel record viene memorizzata in questo campo. È necessario includere questo campo nelle query del beacon e identificare i materiali chiave del beacon appropriati necessari per ricalcolare il beacon. Per ulteriori informazioni, consulta Interrogazione dei beacon in un database multi-tenant.

  • CacheTTL

    La quantità di tempo, in secondi, necessaria per l'immissione di una chiave beacon nella cache locale del beacon prima della scadenza. Questo valore deve essere maggiore di zero. Quando il limite di cache TTL scade, la voce viene rimossa dalla cache locale.

  • (Facoltativo) Una cache

    Se desideri personalizzare il tipo di cache o il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale, specifica il tipo di cache e la capacità di accesso quando inizializzi il portachiavi.

    Il tipo di cache definisce il modello di threading. Il portachiavi Hierarchical fornisce tre tipi di cache che supportano database multitenant: Default,,. MultiThreaded StormTracking

    Se non si specifica una cache, il portachiavi Hierarchical utilizza automaticamente il tipo di cache predefinito e imposta la capacità di ingresso su 1000.

    Default (Recommended)

    Per la maggior parte degli utenti, la cache predefinita soddisfa i requisiti di threading. La cache predefinita è progettata per supportare ambienti con molti multithread. Quando una voce relativa ai materiali delle chiavi di branch scade, la cache predefinita impedisce la chiamata di più thread AWS KMS notificando a un thread che la voce relativa ai materiali della chiave di branch sta per scadere con 10 secondi di anticipo. Ciò garantisce che solo un thread invii una richiesta di aggiornamento della cache AWS KMS .

    Per inizializzare il tuo portachiavi gerarchico con una cache predefinita, specifica il seguente valore:

    • Capacità di accesso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

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

    Il valore predefinito e le StormTracking cache supportano lo stesso modello di threading, ma è sufficiente specificare la capacità di ingresso per inizializzare il portachiavi gerarchico con la cache predefinita. Per personalizzazioni più granulari della cache, usa la cache. StormTracking

    MultiThreaded

    La MultiThreaded cache è sicura da usare in ambienti multithread, ma non fornisce alcuna funzionalità per ridurre al minimo AWS KMS le chiamate Amazon DynamoDB. Di conseguenza, quando scade l'immissione di materiali chiave in una filiale, tutti i thread verranno avvisati contemporaneamente. Ciò può comportare più AWS KMS chiamate per aggiornare la cache.

    Per inizializzare il tuo portachiavi Hierarchical con una MultiThreaded cache, specifica i seguenti valori:

    • Capacità di ingresso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

    • Entry Poting Tail Size: definisce il numero di elementi da potare se viene raggiunta la capacità di ingresso.

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

    La StormTracking cache è progettata per supportare ambienti fortemente multithread. Quando una voce relativa ai materiali della chiave di filiale scade, la StormTracking cache impedisce la chiamata di più thread AWS KMS notificando in anticipo a un thread che la voce relativa ai materiali chiave della branch sta per scadere. Ciò garantisce che solo un thread invii una richiesta di aggiornamento della cache AWS KMS .

    Per inizializzare il tuo portachiavi Hierarchical con una StormTracking cache, specifica i seguenti valori:

    • Capacità di ingresso: limita il numero di voci relative ai materiali chiave della filiale che possono essere archiviate nella cache locale.

    • Dimensione della coda di potatura d'ingresso: definisce il numero di materiali chiave del ramo da potare alla volta.

      Valore predefinito: 1 voce

    • Periodo di tolleranza: definisce il numero di secondi prima della scadenza in cui viene effettuato un tentativo di aggiornare i materiali chiave della filiale.

      Valore predefinito: 10 secondi

    • Intervallo di grazia: definisce il numero di secondi tra i tentativi di aggiornamento dei materiali chiave del ramo.

      Valore predefinito: 1 secondo

    • Fan out: definisce il numero di tentativi simultanei che è possibile effettuare per aggiornare i materiali chiave della filiale.

      Valore predefinito: 20 tentativi

    • In flight time to live (TTL): definisce il numero di secondi che mancano al timeout di un tentativo di aggiornamento dei materiali chiave della filiale. Ogni volta che la cache ritorna NoSuchEntry in risposta a unaGetCacheEntry, quella chiave di ramo viene considerata in esecuzione finché la stessa chiave non viene scritta con una PutCache voce.

      Valore predefinito: 20 secondi

    • Sospensione: definisce il numero di secondi in cui un thread deve dormire se fanOut viene superato il limite.

      Valore predefinito: 20 millisecondi

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

L'esempio seguente inizializza un portachiavi Hierarchical con il branch key ID supplier creato nel passaggio 2, un TLL con limite di cache di 600 secondi e una capacità di ingresso di 1000.

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(1000) .build()) .build(); final IKeyring hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var keyringInput = new CreateAwsKmsHierarchicalKeyringInput { KeyStore = keystore, BranchKeyIdSupplier = branchKeyIdSupplier, TtlSeconds = 600, Cache = new CacheType { Default = new DefaultCache { EntryCapacity = 1000 } } }; var hierarchicalKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput);