Gerenciamento das chaves de criptografia
Nesta página
- Componentes de criptografia
- Serviços de gerenciamento de chaves suportados
- Motivos para usar um sistema de gerenciamento de chaves remotas
- Gerenciar o nome alternativo de uma Data Encryption Key (DEK)
- Criar uma Data Encryption Key (DEK) com um nome alternativo
- Usar nomes alternativos de Chaves em um esquema de criptografia automática
- Procedimento: girar chaves de encriptação usando o Mongo Shell
- Excluir uma Data Encryption Key (DEK)
- Saiba mais
Neste guia, você pode aprender como gerenciar suas chaves de encriptação com um Sistema de gerenciamento de chaves (KMS) em seu aplicativo habilitado para criptografia no nível do campo (CSFLE) do lado do cliente.
Componentes de criptografia
O MongoDB usa os seguintes componentes para executar a criptografia no nível do campo do lado do cliente:
Data Encryption Keys (DEK)s
Chaves mestras do cliente (CMK)s
Key Vault collections
Sistema de Gerenciamento de Chaves (KMS)
Para saber mais sobre chaves e cofres de chaves, veja Chaves e cofres de chaves.
Serviços de gerenciamento de chaves suportados
A criptografia de nível de campo do lado do cliente oferece suporte aos seguintes provedores de sistema de gerenciamento de chaves:
KMS do Amazon Web Services
Azure Key Vault
KMS do Google Cloud
Qualquer sistema de gerenciamento de chaves compatível com KMIP
Provedor de chaves locais (somente para testes)
A versão do protocolo KMIP padrão é 1.2. Você pode configurar o MongoDB para usar a versão KMIP 1.0 ou 1.1 no arquivo de configuração do servidor MongoDB.
Para saber mais sobre esses fornecedores, incluindo diagramas que mostram como seu aplicativo os utiliza para executar a criptografia no nível do campo do lado do cliente, consulte Fornecedores CSFLE KMS.
Motivos para usar um sistema de gerenciamento de chaves remotas
O uso de um sistema de gerenciamento de chaves remoto para gerenciar a chave mestra do cliente tem as seguintes vantagens em relação ao uso do sistema de arquivos local para hospedar a CMK:
Armazenamento seguro da chave com auditoria de acesso
Risco reduzido de ter problemas de permissão de acesso
Disponibilidade e distribuição da chave para clientes remotos
Backup e recuperação automatizados de chaves
Gerenciamento centralizado do ciclo de vida da chave de encriptação
Além disso, para os seguintes provedores de KMS, seu KMS criptografa e descriptografa remotamente sua Chave de criptografia de dados, garantindo que sua Chave Mestre do cliente nunca seja exposta ao seu aplicativo habilitado para CSFLE:
KMS do Amazon Web Services
Azure Key Vault
KMS do Google Cloud
Gerenciar o nome alternativo de uma Data Encryption Key (DEK)
Você pode atribuir nomes alternativos a uma Data Encryption Key (DEK) para facilitar a referência à chave. Atribuir nomes alternativos permite executar as seguintes ações:
Fazer referência a uma DEK de outras formas do que pelo campo
_id
.Atribua dinamicamente DEKs no tempo de execução.
Criar uma Data Encryption Key (DEK) com um nome alternativo
Importante
Pré-requisitos
Antes de adicionar um novo nome alternativo da chave, você deve criar um índice único no campo keyAltNames
. A criptografia do nível do campo no lado do cliente depende da singularidade imposta pelo servidor dos principais nomes alternativos.
Para saber como criar um índice único, consulte Índices únicos.
O exemplo a seguir cria uma Chave de criptografia de dados com um nome alternativo. Selecione a guia que corresponde ao idioma do seu driver:
var autoEncryptionOpts = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }; var encryptedClient = Mongo( connectionString, autoEncryptionOpts ); var clientEncryption = encryptedClient.getClientEncryption(); var masterKey = { "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", }; var keyVault = encryptedClient.getKeyVault(); var keyId = keyVault.createKey("aws", masterKey, ["<Your Key Alt Name>"]);
var keyVaultClient = new MongoClient(connectionString); var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders); var clientEncryption = new ClientEncryption(clientEncryptionOptions); var dataKeyOptions = new DataKeyOptions( alternateKeyNames: new[] { "<Your Key Alt Name>" }, masterKey: new BsonDocument { { "<Your dataKeyOpts Keys>", "<Your dataKeyOpts Values>" }, }); var dataKeyId = clientEncryption.CreateDataKey("<Your KMS Provider>", dataKeyOptions, CancellationToken.None);
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(KeyVaultNamespace).SetKmsProviders(kmsProviders) keyVaultClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI)) if err != nil { return fmt.Errorf("Client connect error %v", err) } clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts) if err != nil { return fmt.Errorf("NewClientEncryption error %v", err) } defer func() { _ = clientEnc.Close(context.TODO()) }() masterKey := map[string]interface{}{ "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", } dataKeyOpts := options.DataKey(). SetMasterKey(masterKey). SetKeyAltNames([]string{"<Your Key Alt Name>"}) dataKeyID, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts) if err != nil { return fmt.Errorf("create data key error %v", err) }
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings); BsonDocument masterKeyProperties = new BsonDocument(); masterKeyProperties.put("provider", new BsonString("<Your KMS Provider>")); masterKeyProperties.put("<Your dataKeyOpts Key>", new BsonString("<Your dataKeyOpts Value>")); List keyAltNames = new ArrayList<String>(); keyAltNames.add("<Your Key Alt Name>"); BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions().masterKey(masterKeyProperties).keyAltNames(keyAltNames));
const encryption = new ClientEncryption(client, { keyVaultNamespace, kmsProviders, }); const masterKey = { "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", }; const key = await encryption.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["<Your Key Alt Name>"], });
client = MongoClient(connection_string) client_encryption = ClientEncryption( kms_providers, key_vault_namespace, client, CodecOptions(uuid_representation=STANDARD), ) master_key={ "<Your dataKeyOpts Key>" : "<Your dataKeyOpts Value>"} data_key_id = client_encryption.create_data_key(provider, master_key, key_alt_names=["<Your Key Alt Name>"])
Para saber mais sobre objetos dataKeyOpts
e kmsProviders
, consulte Fornecedores de KMS CSFLE.
Usar nomes alternativos de Chaves em um esquema de criptografia automática
Os esquemas de criptografia contêm regras especificadas pelo usuário que identificam quais campos devem ser criptografados e como criptografar esses campos. Em suas regras de criptografia, você pode especificar nomes de chaves alternativos para a chave de encriptação de dados que criptografa seu campo.
Você deve se referir a um nome alternativo de chave com um ponteiro JSON. Um ponteiro JSON é uma string prefixada com um caractere "/"
que pode ser usada para acessar um valor de campo específico no mesmo documento ou em outro documento. Use ponteiros JSON para referenciar um campo em sua query ou documento de atualização que contém o valor do nome alternativo da chave.
Importante
Não é possível usar nome alternativo para um campo criptografado de forma determinística
Você não pode referenciar uma DEK pelo nome alternativo ao criptografar um campo com o algoritmo de criptografia determinístico. Para criptografar seu campo deterministicamente, você deve especificar o _id
da chave que deseja usar para criptografar seu campo.
Fazer referência a um nome alternativo da chave em um esquema de criptografia
Considere o seguinte esquema de criptografia que criptografa o campo salary
:
{ "<database>.<collection>": { "bsonType": "object", "properties": { "salary": { "encrypt": { "bsonType": "int", "keyId": "/fieldWithAltName", "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" } } } } }
O campo keyId
do esquema contém um ponteiro JSON para referenciar o campo fieldWithAltName
dentro dos documentos sendo codificados.
O valor de fieldWithAltName
do documento abaixo é my-alt-name
:
{ "name": "Jon Doe", "salary": 45000, "fieldWithAltName": "my-alt-name" }
O campo salary
é criptografado pela DEK que tem o nome alternativo my-alt-name
.
Atribuir chaves dinamicamente no Runtime
Você pode usar nomes de chave alternativos para definir dinamicamente a chave de criptografia de dados de um campo em tempo de execução. Use essa funcionalidade para criptografar documentos individuais com diferentes DEKs usando o mesmo esquema de criptografia.
Por exemplo, considere os seguintes documentos:
{ "name": "Jon Doe", "salary": 45000, "fieldWithAltName": "my-alt-name" }, { "name": "Jane Smith", "salary": 70000, "fieldWithAltName": "my-other-alt-name" }
Você insere os documentos anteriores utilizando um cliente habilitado para CSFLE configurada com o esquema de criptografia do exemplo anterior.
No esquema de criptografia, o campo salary.encrypt.keyId
contém um ponteiro JSON no campo fieldWithAltName
do documento inserido. Como resultado, os campos salary
nos dois documentos de exemplo são criptografados usando uma DEK específica para o documento individual. As chaves são atribuídas dinamicamente no tempo de execução.
Procedimento: girar chaves de encriptação usando o Mongo Shell
Com a versão 1.5 e posterior do Mongo Shell, você pode girar chaves de encriptação usando o método rewrapManyDataKey
. O método rewrapManyDataKey
descriptografa automaticamente diversas chaves de dados e as criptografa novamente usando uma chave mestra do cliente especificada. Em seguida, ele atualiza as chaves giradas na key vault collection. Este método permite girar chaves de encriptação com base em dois argumentos opcionais:
Um filtro utilizado para especificar quais chaves devem ser rotacionadas. Se nenhuma chave de dados corresponder ao filtro fornecido, nenhuma chave será rotacionada. Omita o filtro para rotacionar todas as chaves na sua Key Vault Collection.
Um objeto que representa uma nova CMK. Omitir este objeto para rotacionar as chaves de dados usando suas CMKs atuais.
O rewrapManyDataKey
utiliza a seguinte sintaxe:
keyVault = db.getKeyVault() keyVault.rewrapManyDataKey( { "<Your custom filter>" }, { provider: "<KMS provider>", masterKey: { "<dataKeyOpts Key>" : "<dataKeyOpts Value>" } } )
Para saber mais sobre o objeto dataKeyOpts
para seu fornecedor de KMS, consulte Serviços de gerenciamento de chaves suportados.
Excluir uma Data Encryption Key (DEK)
Você pode excluir uma chave de encriptação de dados da Key Vault Collection usando operações de exclusão CRUD padrão. Se você excluir uma DEK, todos os campos criptografados com essa DEK ficarão permanentemente ilegíveis.
Dica
Funcionalidade específica do MongoDB Shell
O MongoDB Shell permite excluir uma DEK pela UUID
usando o seguinte método keyVault.deleteKey()
:
keyVault = db.getKeyVault() keyVault.deleteKey(UUID("<UUID String>"))
Para saber mais sobre as collections do Key Vault, consulte Coleções do Key Vault.
Saiba mais
Para obter tutoriais detalhando como configurar um aplicativo habilitado para CSFLE com cada um dos fornecedores de KMS compatíveis, consulte as páginas a seguir:
Usar criptografia no nível do campo automática no lado do cliente com AWS
Use a criptografia no nível do campo automática no lado do cliente com Azure
Usar criptografia no nível do campo automática no lado do cliente com GCP
Usar criptografia no nível do campo automática no lado do cliente com KMIP
Para ver mais exemplos de esquemas de criptografia, consulte Esquemas de criptografia CSFLE.