AWS KMS Llaveros jerárquicos - AWS Cifrado de bases SDK

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

AWS KMS Llaveros jerárquicos

Se cambió el nombre de nuestra biblioteca de cifrado del lado del cliente por el de SDK de cifrado de bases de AWS datos. En esta guía para desarrolladores, se sigue proporcionando información sobre el cliente de cifrado de DynamoDB.
nota

A partir del 24 de julio de 2023, no se admiten las claves de rama creadas durante la versión preliminar para desarrolladores. Cree nuevas claves de rama para seguir usando el almacén de claves de rama que creó durante la versión preliminar para desarrolladores.

Con el conjunto de claves AWS KMS jerárquico, puede proteger sus materiales criptográficos con una clave KMS de cifrado simétrico sin tener que llamar AWS KMS cada vez que cifra o descifra un registro. Es una buena opción para las aplicaciones que necesitan minimizar las llamadas y las aplicaciones que pueden reutilizar algunos materiales criptográficos sin infringir sus requisitos de seguridad. AWS KMS

El anillo de claves jerárquico es una solución de almacenamiento en caché de materiales criptográficos que reduce el número de AWS KMS llamadas mediante el uso de claves de rama AWS KMS protegidas que se conservan en una tabla de Amazon DynamoDB y, a continuación, el almacenamiento en caché local de los materiales de clave de rama utilizados en las operaciones de cifrado y descifrado. La tabla DynamoDB sirve como almacén de claves de rama que administra y protege las claves de rama. Almacena la clave de rama activa y todas las versiones anteriores de la clave de rama. La clave de rama activa es la versión más reciente de la clave de rama. El conjunto de claves jerárquico utiliza una clave de datos única para cifrar cada campo y cifra cada clave de datos con una clave de encapsulación única derivada de la clave de rama activa. El conjunto de claves jerárquico depende de la jerarquía establecida entre las claves de rama activas y las claves de encapsulación derivadas.

El conjunto de claves jerárquico suele utilizar cada versión de clave de rama para satisfacer múltiples solicitudes. Sin embargo, usted controla el grado en que se reutilizan las claves de rama activas y determina la frecuencia con la que se gira la clave de rama activa. La versión activa de la clave de rama permanece activa hasta que la gire. Las versiones anteriores de la clave de rama activa no se utilizarán para realizar operaciones de cifrado, pero sí se pueden consultar y utilizar en las operaciones de descifrado.

Al crear una instancia del conjunto de claves jerárquico, se crea una caché local. Se especifica un límite de caché que define el tiempo máximo durante el que los materiales de las claves de ramificación se almacenan en la caché local antes de que caduquen y se expulsen de la caché. El anillo de claves jerárquico realiza una AWS KMS llamada para descifrar la clave de rama y reunir los materiales de la clave de rama la primera vez que se especifica a en una operación. branch-key-id A continuación, los materiales de la clave de rama se almacenan en la memoria caché local y se reutilizan para todas las operaciones de cifrado y descifrado que la branch-key-id especifique hasta que caduque el límite de la memoria caché. Almacenar los materiales de las claves de rama en la memoria caché local reduce las llamadas. AWS KMS Por ejemplo, considere un límite de caché de 15 minutos. Si realizas 10 000 operaciones de cifrado dentro de ese límite de caché, el conjunto de AWS KMS claves tradicional necesitaría realizar 10 000 AWS KMS llamadas para cumplir con 10 000 operaciones de cifrado. Si tiene uno activobranch-key-id, el conjunto de claves jerárquico solo necesita realizar una AWS KMS llamada para realizar 10 000 operaciones de cifrado.

La memoria caché local consta de dos particiones, una para las operaciones de cifrado y otra para las operaciones de descifrado. La partición de cifrado almacena los materiales de clave de rama recopilados a partir de la clave de rama activa y los reutiliza para todas las operaciones de cifrado hasta que venza el límite de memoria caché. La partición de descifrado almacena los materiales de clave de rama reunidos para otras versiones de claves de rama identificadas en las operaciones de descifrado. La partición de descifrado puede almacenar varias versiones de materiales de claves de rama activas a la vez. Cuando se configura para usar un proveedor de ID de clave de rama para una base de datos de multitenencia, la partición de cifrado también puede almacenar varias versiones de materiales de clave de rama a la vez. Para obtener más información, consulte Uso del conjunto de claves jerárquico con bases de datos de multitenencia.

nota

Todas las menciones al conjunto de claves jerárquicas en el SDK de cifrado de AWS bases de datos se refieren al conjunto de claves jerárquico. AWS KMS

Funcionamiento

Los siguientes tutoriales describen cómo el conjunto de claves jerárquico reúne los materiales de cifrado y descifrado, y las diferentes llamadas que realiza el conjunto de claves para las operaciones de cifrado y descifrado. Para obtener detalles técnicos sobre los procesos de derivación de claves de ajuste y cifrado de claves de datos de texto no cifrado, consulte Detalles técnicos del conjunto de claves jerárquico de AWS KMS.

Cifra y firma

El siguiente tutorial describe cómo el conjunto de claves jerárquico reúne los materiales de cifrado y obtiene una clave de encapsulamiento única.

  1. El método de cifrado solicita materiales de cifrado al conjunto de claves jerárquico. El conjunto de claves genera una clave de datos de texto no cifrado y, a continuación, comprueba si hay materiales de derivación válidos en la memoria caché local para generar la clave de encapsulamiento. Si hay materiales de clave de rama válidos, el conjunto de claves continúa con el paso 5.

  2. Si no hay ningún material de clave de rama válido, el conjunto de claves jerárquico consulta el almacén de claves de rama en busca de la clave de rama activa.

    1. El almacén de claves de bifurcación llama AWS KMS para descifrar la clave de bifurcación activa y devuelve la clave de bifurcación activa en texto plano. Los datos que identifican la clave de rama activa se serializan para proporcionar datos autenticados adicionales (AAD) en la llamada de descifrado a AWS KMS.

    2. El almacén de claves de rama devuelve la clave de rama en texto no cifrado y los datos que la identifican, como la versión de la clave de rama.

  3. El conjunto de claves jerárquico reúne los materiales de las claves de rama (las versiones de las claves de rama y las claves de rama en texto no cifrado) y guarda una copia de los mismos en la memoria caché local.

  4. El conjunto de claves jerárquico obtiene una clave de ajuste única de la clave de rama de texto simple y de una sal aleatoria de 16 bytes. Utiliza la clave de encapsulación derivada para cifrar una copia de la clave de datos de texto no cifrado.

El método de cifrado utiliza los materiales de cifrado para cifrar y firmar el registro. Para obtener más información sobre cómo se cifran y firman los registros en el SDK de cifrado de bases de datos de AWS , consulte Encrypt and sign.

Descifrado y verificación

En el siguiente tutorial, se describe cómo el conjunto de claves jerárquico reúne los materiales de descifrado y descifra la clave de datos cifrados.

  1. El método de descifrado identifica la clave de datos cifrada en el campo de descripción del material del registro cifrado y la pasa al conjunto de claves jerárquico.

  2. El conjunto de claves jerárquico deserializa los datos que identifican la clave de datos cifrada, incluida la versión de la clave de rama, la sal de 16 bytes y otra información que describe cómo se cifró la clave de datos.

    Para obtener más información, consulte AWS KMS Detalles técnicos del llavero jerárquico.

  3. El conjunto de claves jerárquico comprueba si hay materiales de clave de rama válidos en la caché local que coincidan con la versión de clave de rama identificada en el paso 2. Si hay materiales de clave de rama válidos, el conjunto de claves continúa con el paso 6.

  4. Si no hay ningún material de clave de rama válido, el conjunto jerárquico consulte el almacén de claves de rama para encontrar la clave de rama que coincida con la versión de clave de rama identificada en el paso 2.

    1. El almacén de claves de bifurcación llama AWS KMS para desencriptar la clave de bifurcación y devuelve la clave de bifurcación activa en texto plano. Los datos que identifican la clave de rama activa se serializan para proporcionar datos autenticados adicionales (AAD) en la llamada de descifrado a AWS KMS.

    2. El almacén de claves de rama devuelve la clave de rama en texto no cifrado y los datos que la identifican, como la versión de la clave de rama.

  5. El conjunto de claves jerárquico reúne los materiales de las claves de rama (las versiones de las claves de rama y las claves de rama en texto no cifrado) y guarda una copia de los mismos en la memoria caché local.

  6. El conjunto de claves jerárquico utiliza los materiales de clave de rama ensamblados y la sal de 16 bytes identificada en el paso 2 para reproducir la clave de encapsulamiento única que cifró la clave de datos.

  7. El conjunto de claves jerárquico utiliza la clave de encapsulación para descifrar la clave de datos y devuelve la clave de datos en texto no cifrado.

El método de descifrado utiliza los materiales de descifrado y la clave de datos de texto no cifrado para descifrar y verificar el registro. Para obtener más información sobre cómo se descifran y verifican los registros en el SDK de cifrado de AWS bases de datos, consulte Descifrar y verificar.

Requisitos previos

El SDK AWS de cifrado de bases de datos no requiere ni depende de ninguno. Cuenta de AWS Servicio de AWS Sin embargo, el conjunto de claves jerárquico depende de Amazon AWS KMS DynamoDB.

Para utilizar un conjunto de claves jerárquico, necesita un cifrado simétrico con permisos de KMS:Decrypt. AWS KMS key También puede utilizar una clave multirregional de cifrado simétrico. Para obtener información detallada acerca de los permisos para AWS KMS keys, consulte Autenticación y control de acceso en la Guía para desarrolladores de AWS Key Management Service .

Antes de poder crear y usar un conjunto de claves jerárquico, debe crear su almacén de claves de rama y rellenarlo con la primera clave de rama activa.

Paso 1: Configurar un nuevo servicio de almacenamiento de claves

El servicio de almacén de claves ofrece varias operaciones, como CreateKeyStore y CreateKey, para ayudarle a reunir los requisitos previos del conjunto de claves jerárquico y a gestionar el almacén de claves de su rama.

El siguiente ejemplo crea un servicio de almacenamiento de claves. Debe especificar un nombre de tabla de DynamoDB que sirva como nombre del almacén de claves de rama, un nombre lógico para el almacén de claves de rama y el ARN de clave de KMS que identifica la clave de KMS que protegerá las claves de rama.

El nombre del almacén de claves lógico está enlazado criptográficamente a todos los datos almacenados en la tabla para simplificar las operaciones de restauración de DynamoDB. El nombre del almacén de claves lógicas puede ser el mismo que el nombre de la tabla de DynamoDB, pero no tiene por qué serlo. Se recomienda encarecidamente especificar el nombre de la tabla de DynamoDB como nombre de la tabla lógica cuando configure por primera vez el servicio de almacén de claves. Debe especificar siempre el mismo nombre de tabla lógica. En caso de que el nombre del almacén de claves de la rama cambie después de restaurar la tabla de DynamoDB a partir de una copia de seguridad, el nombre del almacén de claves lógico se asigna al nombre de la tabla de DynamoDB que especifique para garantizar que el conjunto de claves jerárquico pueda seguir accediendo al almacén de claves de la rama.

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);
Paso 2: llamar a CreateKeyStore para crear un almacén de claves de rama

La siguiente operación crea el almacén de claves de rama que conservará y protegerá las claves de rama.

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

La operación de CreateKeyStore crea una tabla de DynamoDB con el nombre de tabla que especificó en el paso 1 y los siguientes valores obligatorios.

Clave de partición Clave de clasificación
Tabla base branch-key-id type
nota

Puede crear manualmente la tabla de DynamoDB que sirve como almacén de claves de rama en lugar de utilizar la operación. CreateKeyStore Si decide crear manualmente el almacén de claves de rama, debe especificar los siguientes valores de cadena para las claves de partición y ordenación:

  • Clave de partición: branch-key-id

  • El criterio de ordenación: type

Paso 3: llame a CreateKey para crear una nueva clave de rama activa

La siguiente operación crea una nueva clave de rama activa con la clave de KMS que especificó en el paso 1 y agrega la clave de rama activa a la tabla de DynamoDB que creó en el paso 2.

Al llamar a CreateKey, puede optar por especificar los siguientes valores opcionales.

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

En primer lugar, la operación CreateKey genera los siguientes valores.

A continuación, la CreateKey operación llama a kms: GenerateDataKeyWithoutPlaintext mediante la siguiente solicitud.

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

A continuación, la CreateKey operación llama a kms: ReEncrypt para crear un registro activo para la clave de sucursal mediante la actualización del contexto de cifrado.

Por último, la CreateKey operación llama a ddb: TransactWriteItems para escribir un nuevo elemento que conserve la clave de rama en la tabla que creó en el paso 2. El objeto tiene los siguientes atributos:

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

Crear un conjunto de claves jerárquico

Para inicializar el conjunto de claves jerárquico, debe proporcionar los siguientes valores:

  • Un nombre de almacén de claves de rama

    Nombre de la tabla de DynamoDB que creó como almacén de claves de sucursal.

  • Un tiempo de vida límite de la memoria caché (TTL)

    La cantidad de tiempo en segundos que se puede utilizar una entrada de material de clave de la memoria caché local antes de que caduque. El límite de caché TTL determina la frecuencia con la que el cliente llama AWS KMS para autorizar el uso de las claves de rama. El valor debe ser mayor que cero. Cuando el TTL límite de caché vence, la entrada se expulsa de la caché local.

  • Un identificador de clave de rama

    La branch-key-id que identifica la clave de rama activa en su almacén de clave de rama.

    nota

    Para inicializar el conjunto de claves jerárquico para su uso por varios inquilinos, debe especificar un proveedor de ID de sucursal en lugar de una branch-key-id. Para obtener más información, consulte Uso del conjunto de claves jerárquico con bases de datos de multitenencia.

  • (Opcional) Una lista de tokens de concesión

    Si controla el acceso a la clave KMS de su conjunto de claves jerárquico mediante concesiones, debe proporcionar todos los tokens de concesión necesarios al inicializar el conjunto de claves.

Los siguientes ejemplos muestran cómo inicializar un conjunto de claves jerárquico con el SDK de cifrado de AWS bases de datos para el cliente DynamoDB. El siguiente ejemplo especifica un TTL con un límite de caché de 600 segundos.

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

Rote la clave de rama activa

Solo puede haber una versión activa para cada clave de rama a la vez. El conjunto de claves jerárquico suele utilizar cada versión de clave de rama activa para satisfacer múltiples solicitudes. Sin embargo, usted controla el grado en que se reutilizan las claves de rama activas y determina la frecuencia con la que se gira la clave de rama activa.

Las claves de rama no se utilizan para cifrar claves de datos de texto simple. Se utilizan para obtener las claves de encapsulamiento únicas que cifran las claves de datos de texto no cifrado. El proceso de derivación de la clave de encapsulamiento produce una clave de encapsulamiento única de 32 bytes con 28 bytes de asignación al azar. Esto significa que una clave de ramificación puede obtener más de 79 octillones, o 296, claves de encapsulamiento únicas antes de que se produzca un desgaste criptográfico. A pesar de este riesgo de agotamiento muy bajo, es posible que deba rotar la clave de rama activa debido a reglas comerciales o contractuales o regulaciones gubernamentales.

La versión activa de la clave de rama permanece activa hasta que la rotes. Las versiones anteriores de la clave de rama activa no se utilizarán para realizar operaciones de cifrado ni para obtener nuevas claves de encapsulamiento. Sin embargo, aún se pueden consultar y proporcionar claves de encapsulamiento para descifrar las claves de datos que cifraron mientras estaban activas.

Utilice la operación VersionKey del servicio de almacenamiento de claves para rotar la clave de rama activa. Al girar la clave de rama activa, se crea una nueva clave de rama para sustituir a la versión anterior. La branch-key-id no cambia al girar la clave de rama activa. Debe especificar la branch-key-id que identifica clave de rama activa actual cuando llame a VersionKey.

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

Uso del conjunto de claves jerárquico con bases de datos de multitenencia

Puede utilizar la jerarquía de claves establecida entre las claves de rama activas y sus claves de encapsulación derivadas para admitir bases de datos de multitenencia creando una clave de rama para cada inquilino de la base de datos. A continuación, el conjunto de claves jerárquico cifra y firma todos los datos de un inquilino determinado con su clave de rama distinta. Esto le permite almacenar los datos de multitenencia en una única base de datos y aislar los datos de los inquilinos por clave de rama.

Cada inquilino tiene su propia clave de rama que se define mediante una clave única branch-key-id. Solo puede haber una versión activa de cada branch-key-id a la vez.

Proveedor de ID de clave de sucursal

Antes de poder inicializar su conjunto de claves jerárquico para su uso de multitenencia, debe crear una clave de rama para cada inquilino y crear un proveedor de ID de clave de rama. El proveedor de la clave de sucursal utiliza los campos almacenados en el contexto de cifrado para determinar qué clave de sucursal del inquilino es necesaria para descifrar un registro. De forma predeterminada, solo las claves de partición y clasificación se incluyen en el contexto de cifrado. Sin embargo, puede utilizar la acción SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT criptográfica para incluir campos adicionales en el contexto de cifrado.

nota

Para utilizar la acción SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT criptográfica, debe utilizar la versión 3.3 o posterior del SDK de cifrado de AWS bases de datos. Implemente la nueva versión en todos los lectores antes de actualizar su modelo de datos para SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT incluirla.

Puedes usar el identificador de sucursal del proveedor para crear un nombre descriptivo que te branch-key-ids permita reconocer fácilmente el nombre correcto branch-key-id para el inquilino. Por ejemplo, el nombre descriptivo le permite hacer referencia a una clave de rama como tenant1 en lugar deb3f61619-4d35-48ad-a275-050f87e15122.

Para las operaciones de descifrado, puede configurar de forma estática un único conjunto de claves jerárquicas para restringir el descifrado a un único usuario, o puede utilizar el proveedor del identificador de clave de sucursal para identificar qué inquilino es responsable de descifrar un registro.

En primer lugar, siga los pasos 1 y 2 de los procedimientos de Requisitos previos A continuación, utilice los siguientes procedimientos para crear una clave de rama para cada inquilino, crear un proveedor de ID de clave de rama e inicializar su conjunto de claves jerárquicas para su uso por varios inquilinos.

Paso 1: Cree una clave de rama para cada inquilino de la base de datos

Llamar a CreateKey de cada inquilino en su base de datos.

La siguiente operación crea dos claves de rama con la clave de KMS que especificó al crear el servicio de almacén de claves y agrega las claves de rama a la tabla de DynamoDB que creó para que sirva como almacén de claves de sucursal. La misma clave de KMS debe proteger todas las claves de rama.

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());
Paso 2: crear un proveedor de ID de sucursal

En el siguiente ejemplo, se crean nombres descriptivos para las dos claves de rama creadas en el paso 1 y se pide CreateDynamoDbEncryptionBranchKeyIdSupplier la creación de un proveedor de ID de clave de rama con el SDK de cifrado de AWS bases de datos para el cliente 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;
Paso 3: inicialice su conjunto de claves jerárquico con el proveedor de ID de clave de rama

Para inicializar el conjunto de claves jerárquico, debe proporcionar los siguientes valores:

  • Un nombre de almacén de claves de rama

  • Un tiempo límite de vida de la memoria caché (TTL)

  • Un proveedor de ID de clave de rama

  • (Opcional) Una caché

    Si desea personalizar el tipo de caché o el número de entradas de materiales clave de rama que se pueden almacenar en la caché local, especifique el tipo de caché y la capacidad de entrada al inicializar el conjunto de claves.

    El tipo de caché define el modelo de subprocesamiento. El conjunto de claves jerárquico proporciona tres tipos de caché que admiten bases de datos multiusuario: predeterminada,,. MultiThreaded StormTracking

    Si no especifica una caché, el conjunto de claves jerárquico utiliza automáticamente el tipo de caché predeterminado y establece la capacidad de entrada en 1000.

    Default (Recommended)

    La mayoría de usuarios no necesitará modificar sus requisitos de subprocesamiento. La caché predeterminada está diseñada para admitir entornos con muchos subprocesos múltiples. Cuando caduca una entrada de materiales de clave de rama, la caché predeterminada evita que varios subprocesos llamen al sistema AWS KMS notificando a un subproceso que la entrada de materiales de clave de rama va a caducar con 10 segundos de antelación. Esto garantiza que solo un subproceso envíe una solicitud AWS KMS para actualizar la caché.

    Para inicializar el conjunto de claves jerárquico con una caché predeterminada, especifique el siguiente valor:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

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

    La caché predeterminada y la StormTracking caché admiten el mismo modelo de subprocesos, pero solo es necesario especificar la capacidad de entrada para inicializar el conjunto de claves jerárquico con la caché predeterminada. Para personalizaciones de caché más detalladas, utilice la caché. StormTracking

    MultiThreaded

    El uso de la MultiThreaded memoria caché es seguro en entornos de subprocesos múltiples, pero no proporciona ninguna funcionalidad para minimizar las llamadas de Amazon AWS KMS DynamoDB. Como resultado, cuando una entrada de materiales clave de rama caduque, se notificará a todos los subprocesos al mismo tiempo. Esto puede provocar varias AWS KMS llamadas para actualizar la memoria caché.

    Para inicializar el conjunto de claves jerárquico con una MultiThreaded caché, especifique los siguientes valores:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

    • Tamaño de la cola de poda de entrada: define el número de entradas que se deben podar si se alcanza la capacidad de entrada.

    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 memoria caché está diseñada para soportar entornos con muchos subprocesos múltiples. Cuando una entrada de materiales de clave de rama caduca, la StormTracking caché evita que varios subprocesos AWS KMS llamen, ya que notifica a un subproceso que la entrada de materiales de clave de rama va a caducar con antelación. Esto garantiza que solo un subproceso envíe una solicitud AWS KMS para actualizar la caché.

    Para inicializar el conjunto de claves jerárquico con una StormTracking caché, especifique los siguientes valores:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

    • Tamaño de la cola de poda de entrada: define el número de entradas de materiales clave para la rama que se deben podar a la vez.

      Valor predeterminado: 1 entrada

    • Período de gracia: define el número de segundos antes de la caducidad durante los que se intenta actualizar los materiales clave de la rama.

      Valor predeterminado: 10 segundos

    • Intervalo de gracia: define el número de segundos entre los intentos de actualizar los materiales clave de la rama.

      Valor predeterminado: 1 segundo

    • Amplificador: define el número de intentos simultáneos que se pueden realizar para actualizar los materiales clave de la rama.

      Valor predeterminado: 20 intentos

    • En tiempo de vuelo hasta la vida útil (TTL): define el número de segundos hasta que se agota el tiempo de espera para intentar actualizar los materiales clave de la rama. Cada vez que la caché devuelve NoSuchEntry en respuesta a un GetCacheEntry, se considera que esa clave de rama está en tránsito hasta que se escribe la misma clave con una entrada PutCache.

      Valor predeterminado: 20 segundos

    • Suspender: define el número de segundos que un hilo debe permanecer inactivo si fanOut se supera.

      Valor predeterminado: 20 milisegundos

    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 } };
  • (Opcional) Una lista de tokens de concesión

    Si controla el acceso a la clave KMS de su conjunto de claves jerárquico mediante concesiones, debe proporcionar todos los tokens de concesión necesarios al inicializar el conjunto de claves.

Los siguientes ejemplos inicializan un conjunto de claves jerárquico con el proveedor de ID de clave de sucursal creado en el paso 2, un TLL con un límite de caché de 600 segundos y un tamaño de caché máximo de 1000. En este ejemplo, se inicializa un conjunto de claves jerárquico con el SDK de cifrado de AWS bases de datos para el cliente 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);

Uso del conjunto de claves jerárquico para el cifrado para búsquedas

El cifrado para búsquedas le permite buscar registros cifrados sin necesidad de descifrar toda la base de datos. Esto se logra indexando el valor de texto no cifrado de un campo cifrado con una baliza. Para implementar un cifrado para búsquedas, debe utilizar un conjunto de claves jerárquico.

La operación CreateKey de almacenamiento de claves genera tanto una clave de rama como una clave de baliza. La clave de rama se utiliza en las operaciones de cifrado y descifrado de registros. La clave de baliza se utiliza para generar balizas.

La clave de rama y la clave de baliza están protegidas por lo mismo AWS KMS key que especificó al crear el servicio de almacenamiento de claves. Una vez que la CreateKey operación llama AWS KMS para generar la clave de sucursal, llama a kms: GenerateDataKeyWithoutPlaintext una segunda vez para generar la clave de baliza mediante la siguiente solicitud.

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

Tras generar ambas claves, la CreateKey operación llama a ddb: TransactWriteItems para escribir dos nuevos elementos que conservarán la clave de rama y la clave de baliza en tu almacén de claves de sucursal.

Al configurar una baliza estándar, el SDK de cifrado de AWS bases de datos consulta la clave de baliza en el almacén de claves de la sucursal. A continuación, utiliza una función de derivación de extract-and-expand claves (HKDF) basada en HMAC para combinar la clave de baliza con el nombre de la baliza estándar y crear la clave HMAC para una baliza determinada.

A diferencia de las claves de rama, solo hay una versión de clave de baliza por branch-key-id en un almacén de claves de rama. La clave de la baliza nunca se rota.

Definir la fuente de claves de baliza

Al definir la versión de la baliza para las balizas estándar y compuestas, debe identificar la clave de la baliza y definir un tiempo de vida útil (TTL) límite de caché para los materiales de la clave de la baliza. Los materiales de las claves de baliza se almacenan en una caché local independiente de las claves de rama. El siguiente fragmento muestra cómo definir la keySource para la base de datos de un solo inquilino. Identifique la clave de su baliza por el branch-key-id que está asociada.

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 } }
Definición de la fuente de la baliza en una base de multitenencia

Si tiene una base de datos de multitenencia, debe especificar los siguientes valores al configurar la keySource.

  • keyFieldName

    Define el nombre del campo que almacena la clave branch-key-id asociada a la baliza utilizada para generar las balizas para un inquilino determinado. El keyFieldName puede ser cualquier cadena, pero debe ser única para todos los demás campos de la base de datos. Cuando se escriben nuevos registros en la base de datos, en este campo se almacena la branch-key-id de baliza utilizada para generar las balizas de ese registro. Debe incluir este campo en sus consultas de baliza e identificar los materiales clave de baliza adecuados necesarios para volver a calcular la baliza. Para obtener más información, consulte Consulta de balizas en una base de datos de multitenencia.

  • CacheTTL

    El tiempo en segundos que se puede utilizar una entrada de materiales clave de baliza en la caché de balizas local antes de que caduque. Este valor debe ser mayor que cero. Cuando el TTL límite de caché vence, la entrada se expulsa de la caché local.

  • (Opcional) Una caché

    Si desea personalizar el tipo de caché o el número de entradas de materiales clave de rama que se pueden almacenar en la caché local, especifique el tipo de caché y la capacidad de entrada al inicializar el conjunto de claves.

    El tipo de caché define el modelo de subprocesamiento. El conjunto de claves jerárquico proporciona tres tipos de caché que admiten bases de datos multiusuario: predeterminada,,. MultiThreaded StormTracking

    Si no especifica una caché, el conjunto de claves jerárquico utiliza automáticamente el tipo de caché predeterminado y establece la capacidad de entrada en 1000.

    Default (Recommended)

    La mayoría de usuarios no necesitará modificar sus requisitos de subprocesamiento. La caché predeterminada está diseñada para admitir entornos con muchos subprocesos múltiples. Cuando caduca una entrada de materiales de clave de rama, la caché predeterminada evita que varios subprocesos llamen al sistema AWS KMS notificando a un subproceso que la entrada de materiales de clave de rama va a caducar con 10 segundos de antelación. Esto garantiza que solo un subproceso envíe una solicitud AWS KMS para actualizar la caché.

    Para inicializar el conjunto de claves jerárquico con una caché predeterminada, especifique el siguiente valor:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

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

    La caché predeterminada y la StormTracking caché admiten el mismo modelo de subprocesos, pero solo es necesario especificar la capacidad de entrada para inicializar el conjunto de claves jerárquico con la caché predeterminada. Para personalizaciones de caché más detalladas, utilice la caché. StormTracking

    MultiThreaded

    El uso de la MultiThreaded memoria caché es seguro en entornos de subprocesos múltiples, pero no proporciona ninguna funcionalidad para minimizar las llamadas de Amazon AWS KMS DynamoDB. Como resultado, cuando una entrada de materiales clave de rama caduque, se notificará a todos los subprocesos al mismo tiempo. Esto puede provocar varias AWS KMS llamadas para actualizar la memoria caché.

    Para inicializar el conjunto de claves jerárquico con una MultiThreaded caché, especifique los siguientes valores:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

    • Tamaño de la cola de poda de entrada: define el número de entradas que se deben podar si se alcanza la capacidad de entrada.

    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 memoria caché está diseñada para soportar entornos con muchos subprocesos múltiples. Cuando una entrada de materiales de clave de rama caduca, la StormTracking caché evita que varios subprocesos AWS KMS llamen, ya que notifica a un subproceso que la entrada de materiales de clave de rama va a caducar con antelación. Esto garantiza que solo un subproceso envíe una solicitud AWS KMS para actualizar la caché.

    Para inicializar el conjunto de claves jerárquico con una StormTracking caché, especifique los siguientes valores:

    • Capacidad de entrada: limita el número de entradas de materiales clave de rama que se pueden almacenar en la caché local.

    • Tamaño de la cola de poda de entrada: define el número de entradas de materiales clave para la rama que se deben podar a la vez.

      Valor predeterminado: 1 entrada

    • Período de gracia: define el número de segundos antes de la caducidad durante los que se intenta actualizar los materiales clave de la rama.

      Valor predeterminado: 10 segundos

    • Intervalo de gracia: define el número de segundos entre los intentos de actualizar los materiales clave de la rama.

      Valor predeterminado: 1 segundo

    • Amplificador: define el número de intentos simultáneos que se pueden realizar para actualizar los materiales clave de la rama.

      Valor predeterminado: 20 intentos

    • En tiempo de vuelo hasta la vida útil (TTL): define el número de segundos hasta que se agota el tiempo de espera para intentar actualizar los materiales clave de la rama. Cada vez que la caché devuelve NoSuchEntry en respuesta a un GetCacheEntry, se considera que esa clave de rama está en tránsito hasta que se escribe la misma clave con una entrada PutCache.

      Valor predeterminado: 20 segundos

    • Suspender: define el número de segundos que un hilo debe permanecer inactivo si fanOut se supera.

      Valor predeterminado: 20 milisegundos

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

El siguiente ejemplo inicializa un conjunto de claves jerárquico con el proveedor de ID de clave de sucursal creado en el paso 2, un TLL con un límite de caché de 600 segundos y una capacidad de entrada de 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);