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.
Instalação
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.
Instalar libmongocrypt
Isso pode ser feito de duas maneiras.
Adicione a joia libmongocrypt-helper para o seu
Gemfile
ouBaixe o
libmongocrypt
arquivo de versão , extraia a versão que corresponde ao seu sistema operacional e defina aLIBMONGOCRYPT_PATH
variável de ambiente adequadamente.
Instalar a biblioteca compartilhada de criptografia automática (driver Ruby 2.19+)
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:
Navegue até o centro de download do MongoDB
Na lista suspensa Versão, selecione
x.y.z (current)
(a versão atual mais recente).Na lista suspensa Plataforma, selecione sua plataforma.
Na lista suspensa Pacote, selecione
crypt_shared
.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'
Instale o mongocryptd
(driver Ruby 2.18 ou anterior)
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.
Adicione ffi
ao seu Gemfile
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'
Criar uma chave mestra do cliente
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.
Configurar clientes
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
Criar uma chave de criptografia de dados
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'.
Configurar esquema de criptografia
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.
Limitações conhecidas
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
.
Trabalhando com dados
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>]
Gerenciamento das chaves de criptografia
chave mestra do cliente
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):
Qualquer sistema de gerenciamento de chaves compatível com KMIP
Provedor de chaves locais (somente para testes)
Data Encryption Keys
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 # ...
Rotação das chaves de criptografia
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:...' } } )
Adicionando criptografia automática a um projeto existente
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 onull
nativo).Esta operação requer tempo de inatividade do aplicativo.