Menu Docs
Página inicial do Docs
/ / /
Mongoid
/

Criptografia automática no nível do campo do lado do cliente

Nesta página

  • Instalação
  • Instalar libmongocrypt
  • Instalar a biblioteca compartilhada de criptografia automática (driver Ruby 2.19+)
  • Instale o mongocryptd (driver Ruby 2.18 ou anterior)
  • Adicione ffi ao seu Gemfile
  • Criar uma chave mestra do cliente
  • Configurar clientes
  • Criar uma chave de criptografia de dados
  • Configurar esquema de criptografia
  • Limitações conhecidas
  • Trabalhando com dados
  • Gerenciamento das chaves de criptografia
  • chave mestra do cliente
  • Data Encryption Keys
  • Rotação das chaves de criptografia
  • Adicionando criptografia automática a um projeto existente

Desde a versão 4.2 O MongoDB suporta criptografia no nível do campo do lado do cliente (CSFLE). Esse é um recurso que permite criptografar dados em seu aplicativo antes de enviá-los pela rede para o MongoDB. Com o CSFLE ativado, nenhum produto MongoDB tem acesso aos seus dados de forma não criptografada.

Você pode configurar o CSFLE usando os seguintes mecanismos:

  • Criptografia automática: permite que você execute operações de leitura e gravação criptografadas sem que você precise escrever código para especificar como criptografar campos.

  • Criptografia explícita: permite que você execute operações de leitura e gravação criptografadas por meio da biblioteca de criptografia do driver MongoDB. Você deve especificar a lógica da criptografia com essa biblioteca em todo o seu aplicativo.

Começando com a versão 9.0, O Mongoid suporta o recurso de criptografia automática do CSFLE. Este tutorial orienta você no processo de configuração e uso do CSFLE no Mongoid.

Observação

Este tutorial não aborda todos os recursos do CSLFE. Você pode encontrar mais informações sobre o MongoDB CSFLE na documentação do servidor.

Observação

Se você quiser usar o FLE explícito, siga a documentação do driver Ruby.

Você pode encontrar a descrição detalhada de como instalar as dependências necessárias na documentação do driver.

Observe a versão do driver Ruby que está sendo usada em seu aplicativo e selecione as etapas apropriadas abaixo.

Isso pode ser feito de duas maneiras.

Se você usar a versão 2.19 do driver Ruby e superior, a biblioteca compartilhada de criptografia automática deverá ser instalada seguindo as instruções na página Biblioteca compartilhada de criptografia automática para Queryable Encryption no manual do servidor MongoDB.

As etapas necessárias são as seguintes:

  1. Navegue até o centro de download do MongoDB

  2. Na lista suspensa Versão, selecione x.y.z (current) (a versão atual mais recente).

  3. Na lista suspensa Plataforma, selecione sua plataforma.

  4. Na lista suspensa Pacote, selecione crypt_shared.

  5. Clique em Baixar.

Depois de extraída, certifique-se de que o caminho completo para a biblioteca esteja configurado dentro do seu mongoid.yml da seguinte forma:

development:
clients:
default:
options:
auto_encryption_options:
extra_options:
crypt_shared_lib_path: '/path/to/mongo_crypt_v1.so'

Se você estiver usando uma versão mais antiga do driver Ruby mongocryptd precisará ser instalado manualmente. mongocryptd vem pré-embalado com compilações empresariais do servidor MongoDB (versões 4.2 e mais recentes). Para obter instruções de instalação, consulte o manual do MongoDB.

O driver Ruby do MongoDB usa a joia ffi para chamar funções de libmongocrypt. Como este gem não é uma dependência do driver, ele precisará ser adicionado manualmente ao seu Gemfile:

gem 'ffi'

Uma chave mestra do cliente (CMK) é usada para criptografar chaves de criptografia de dados. A maneira mais fácil é usar uma chave de 96bytes armazenada localmente. Você pode gerar essa chave usando o seguinte código Ruby:

require 'securerandom'
SecureRandom.hex(48) # => "f54ab...."

Mais tarde neste tutorial, assumimos que a chave mestra do cliente está disponível a partir da variável de ambiente CUSTOMER_MASTER_KEY .

Aviso

Usar uma chave mestre local é inseguro. É recomendável usar um KMS remoto para criar e armazenar sua chave mestre. Para fazer isso, siga as etapas de "Configurar uma chave mestre remota" na documentação de criptografia do lado do cliente do MongoDB.

Para obter mais informações sobre como criar uma chave mestre, consulte a seção Criar uma chave mestre de cliente no manual MongoDB.

O CSFLE automático requer algumas configurações adicionais para o cliente MongoDB. Supondo que seu aplicativo tenha apenas um cliente default , adicione o seguinte ao seu mongoid.yml:

development:
clients:
default:
uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority
options:
auto_encryption_options: # This key enables automatic encryption
key_vault_namespace: 'encryption.__keyVault' # Database and collection to store data keys
kms_providers: # Tells the driver where to obtain master keys
local: # We use the local key in this tutorial
key: "<%= ENV['CUSTOMER_MASTER_KEY'] %>" # Key that we generated earlier
extra_options:
crypt_shared_lib_path: '/path/to/mongo_crypt_v1.so' # Only if you use the library

Uma chave de criptografia de dados (DEK) é a chave que você usa para criptografar os campos em seus documentos MongoDB. Você armazena sua chave de criptografia de dados em sua coleção do Key Vault criptografada com sua CMK.

Para criar uma DEK no Mongoid, você pode usar a tarefa db:mongoid:encryption:create_data_key Rake :

% rake db:mongoid:encryption:create_data_key
Created data key with id: 'KImyywsTQWi1+cFYIHdtlA==' for kms provider: 'local' in key vault: 'encryption.__keyVault'.

É possível criar vários DEKs, se necessário.

% rake db:mongoid:encryption:create_data_key
Created data key with id: 'Vxr5m+5cQISjDOruzZgE0w==' for kms provider: 'local' in key vault: 'encryption.__keyVault'.

Você também pode fornecer um nome alternativo para a DEK. Isso permite que você faça referência à DEK pelo nome ao configurar a criptografia para seus campos. Ele também permite que você atribua dinamicamente uma DEK a um campo no tempo de execução.

% rake db:mongoid:encryption:create_data_key -- --key-alt-name=my_data_key
Created data key with id: 'yjF8hKmKQsqGeFGXlB9Sow==' with key alt name: 'my_data_key' for kms provider: 'local' in key vault: 'encryption.__keyVault'.

Agora podemos dizer ao Mongoid o que deve ser criptografado:

class Patient
include Mongoid::Document
include Mongoid::Timestamps
# Tells Mongoid what DEK should be used to encrypt fields of the document
# and its embedded documents.
encrypt_with key_id: 'KImyywsTQWi1+cFYIHdtlA=='
# This field is not encrypted.
field :category, type: String
# This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random
# algorithm.
field :passport_id, type: String, encrypt: {
deterministic: false
}
# This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic
# algorithm.
field :blood_type, type: String, encrypt: {
deterministic: true
}
# This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random
# algorithm and using a different data key.
field :ssn, type: Integer, encrypt: {
deterministic: false, key_id: 'Vxr5m+5cQISjDOruzZgE0w=='
}
embeds_one :insurance
end
class Insurance
include Mongoid::Document
include Mongoid::Timestamps
field :insurer, type: String
# This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random
# algorithm using the key which alternate name is stored in the
# policy_number_key field.
field :policy_number, type: Integer, encrypt: {
deterministic: false,
key_name_field: :policy_number_key
}
embedded_in :patient
end

Observação

Se você estiver desenvolvendo um aplicativo Rails, é recomendável definir preload_models como true em mongoid.yml. Isso garantirá que o Mongoid carregue todos os modelos antes do início do aplicativo e que o esquema de criptografia seja configurado antes que quaisquer dados sejam lidos ou gravados.

  • O MongoDB CSFLE tem algumas limitações descritas na página Limitações de CSFLE no manual do servidor MongoDB. Essas limitações também se aplicam ao Mongoid.

  • O Mongoid não suporta criptografia de relacionamentos embeds_many .

  • Se você usar a opção :key_name_field , o campo deverá ser criptografado usando algoritmo não determinístico. Para criptografar seu campo deterministicamente, você deve especificar a opção :key_id .

O uso automático do CSFLE é transparente em muitas situações.

Observação

Nos exemplos de código abaixo, assumimos que há uma variável unencrypted_client que é um MongoClient conectado ao mesmo banco de dados, mas sem criptografia. Usamos esse cliente para demonstrar o que realmente persiste no banco de dados.

Os documentos podem ser criados como de costume, os campos serão criptografados e descriptografados de acordo com a configuração:

Patient.create!(
category: 'ER',
passport_id: '123456',
blood_type: 'AB+',
ssn: 98765,
insurance: Insurance.new(insurer: 'TK', policy_number: 123456, policy_number_key: 'my_data_key')
)
# Fields are encrypted in the database
unencrypted_client['patients'].find.first
# =>
# {"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4292'),
# "category"=>"ER",
# "passport_id"=><BSON::Binary:0x404080 type=ciphertext data=0x012889b2cb0b1341...>,
# "blood_type"=><BSON::Binary:0x404560 type=ciphertext data=0x022889b2cb0b1341...>,
# "ssn"=><BSON::Binary:0x405040 type=ciphertext data=0x012889b2cb0b1341...>,
# "insurance"=>{"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4293'), "insurer"=>"TK", "policy_number"=><BSON::Binary:0x405920 type=ciphertext data=0x012889b2cb0b1341...>}, "policy_number_key"=>"my_data_key"}

Os campos criptografados usando um algoritmo determinístico podem ser consultados. Somente queries de correspondência exata são suportadas. Para obter mais detalhes, consulte a documentação do servidor.

# We can find documents by deterministically encrypted fields.
Patient.where(blood_type: "AB+").to_a
# => [#<Patient _id: 6447e34d46ebfd3debdd9c39, category: "ER", passport_id: "123456", blood_type: "AB+", ssn: 98765>]

A chave mestra do cliente é a chave que você usa para criptografar suas chaves de criptografia de dados. O MongoDB criptografa automaticamente as chaves de criptografia de dados usando a CMK especificada durante a criação da chave de criptografia de dados.

O CMK é a chave mais sensível no CSFLE. Se a sua CMK estiver comprometida, todos os seus dados criptografados poderão ser descriptografados.

Importante

Certifique-se de armazenar sua chave mestra do cliente (CMK) em um KMS remoto.

Para saber mais sobre por que você deve usar um KMS remoto, consulte Motivos para usar um KMS remoto.

Para visualizar uma lista de todos os provedores KMS suportados, consulte a página Provedores KMS .

O MongoDB CSFLE suporta os seguintes fornecedores de Key Management System (KMS):

As chaves de criptografia de dados podem ser criadas usando a tarefa db:mongoid:encryption:create_data_key Rake . Por padrão, eles são armazenados no mesmo cluster que o banco de dados. No entanto, pode ser uma boa ideia armazenar as chaves separadamente. Isso pode ser feito especificando um cliente de cofre de chave em mongoid.yml:

development:
clients:
key_vault:
uri: mongodb+srv://user:pass@anothercluster.mongodb.net/blog_development?retryWrites=true&w=majority
default:
uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority
options:
auto_encryption_options:
key_vault_client: :key_vault # Client to connect to key vault
# ...

Você pode girar chaves de encriptação usando o método rewrap_many_data_key do driver Ruby. Esse método descriptografa automaticamente várias chaves de encriptação de dados e as criptografa novamente usando uma CMK 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á girada. Omita o filtro para rotacionar todas as chaves na sua Key Vault Collection.

  • Um objeto que representa um novo CMK. Omitir este objeto para girar as chaves de dados usando seus CMKs atuais.

Aqui está um exemplo de rotação de chaves usando o Amazon Web Services KMS:

# Create a key vault client
key_vault_client = Mongo::Client.new('mongodb+srv://user:pass@yourcluster.mongodb.net')
# Or, if you declared the key value client in mongoid.yml, use it
key_vault_client = Mongoid.client(:key_vault)
# Create the encryption object
encryption = Mongo::ClientEncryption.new(
key_vault_client,
key_vault_namespace: 'encryption.__keyVault',
kms_providers: {
aws: {
"accessKeyId": "<IAM User Access Key ID>",
"secretAccessKey": "<IAM User Secret Access Key>"
}
}
)
encryption.rewrap_many_data_key(
{}, # We want to rewrap all keys
{
provider: 'aws',
master_key: {
region: 'us-east-2',
key: 'arn:aws:kms:us-east-2:...'
}
}
)

O CSFLE automático do MongoDB suporta criptografia no local. Você pode ativar a criptografia para seu banco de dados existente e ainda poderá ler dados não criptografados. Todos os dados gravados no banco de dados serão criptografados. No entanto, assim que a criptografia estiver ativada, todas as operações de query usarão dados criptografados:

# We assume that there are two documents in the database, one created without
# encryption enabled, and one with encryption.
# We can still read both.
Patient.all.to_a
# =>
# [#<Patient _id: 644937ac46ebfd02468e58c8, category: "ER", passport_id: "DE-1257", blood_type: "AB+", ssn: 123456>,
# #<Patient _id: 644937c946ebfd029309b912, category: "ER", passport_id: "AT-1545", blood_type: "AB+", ssn: 987654>]
# But when we query, we can see only the latter one.
Patient.where(blood_type: 'AB+').to_a
# => [#<Patient _id: 644937c946ebfd029309b912, category: "ER", passport_id: "AT-1545", blood_type: "AB+", ssn: 987654>]

Se você deseja criptografar o banco de dados existente, isso pode ser feito lendo e write back todos os dados, mesmo sem nenhuma alteração. Se você decidir fazer isso, tenha em mente o seguinte:

  • Valide a integridade dos dados existentes para obter uma fidelidade consistente. O CSFLE é sensível ao tipo - por exemplo, você não pode armazenar números inteiros em um campo declarado como String.

  • Para strings, certifique-se de que os valores vazios sejam sempre strings vazias ou apenas não estejam definidos, mas não nil (o CSFLE não é compatível com o null nativo).

  • Esta operação requer tempo de inatividade do aplicativo.

Voltar

Erros comuns