Criptografia explícita
Nesta página
- Visão geral
- Usar criptografia explícita
- Criar uma Instância do ClientEncryption
- Criptografar campos em operações de leitura e gravação
- Descriptografia manual
- Descriptografia automática
- Exemplo
- Criar uma instância do MongoClient
- Criar uma Instância do ClientEncryption
- Criptografar campos e inserir
- Recuperar documento e descriptografar campos
- Aplicação de criptografia em nível de campo no lado do servidor
- Saiba mais
Visão geral
Saiba como usar o mecanismo de criptografia explícita da CSFLE (Criptografia de Nível de Campo do Lado do Cliente).
A criptografia explícita é um mecanismo no qual você especifica como criptografar e descriptografar campos em seu documento para cada operação executada em seu banco de dados.
A criptografia explícita está disponível nos seguintes produtos MongoDB da versão 4.2 ou posterior:
Servidor MongoDB Community
MongoDB Enterprise Advanced
MongoDB Atlas
Usar criptografia explícita
Para usar criptografia explícita, você deve executar as seguintes ações em seu aplicativo habilitado para CSFLE:
Descriptografar manualmente ou automaticamente os campos em seus documentos
Criar uma Instância do ClientEncryption
Para usar a criptografia explícita, crie uma instância do ClientEncryption
. ClientEncryption
é uma abstração usada entre drivers e mongosh
que encapsula Key Vault Collection e operações doKMS envolvidas na criptografia explícita.
Para criar uma instância do ClientEncryption
, você deve especificar as seguintes informações:
Uma instância do
MongoClient
com acesso à sua coleção do Key VaultO namespace da sua coleção do Key Vault
Um objeto
kmsProviders
configurado com acesso ao provedor de KMS que hospeda sua chave mestra do cliente
Para mais opções do ClientEncryption
, consulte Opções do MongoClient específicas do CSFLE.
Para visualizar trechos de código que mostram como criar uma instância do ClientEncryption
, consulte a seção Exemplo deste guia.
Criptografar campos em operações de leitura e gravação
Você deve atualizar as operações de leitura e gravação em todo o aplicativo para que ele criptografe os campos antes de executar operações de leitura e gravação.
Para criptografar campos, use o método encrypt
de sua instância ClientEncryption
.
Para ver trechos de código que mostram como usar o método encrypt
, consulte a seção Exemplo deste guia.
Descriptografia manual
Você pode descriptografar seus campos criptografados manualmente ou automaticamente ao usar criptografia explícita.
Para descriptografar seus campos manualmente, use o método decrypt
da sua instância do ClientEncryption
.
Para ver trechos de código que mostram como usar o método decrypt
, consulte a seção Exemplo deste guia.
Descriptografia automática
Para descriptografar seus campos automaticamente, configure sua instância do MongoClient
como segue:
Especifique sua coleção do Key Vault
Especifique um objeto
kmsProviders
Se você utilizar o servidor da comunidade MongoDB, configure a opção
bypassAutoEncryption
paraTrue
Observação
A descriptografia automática está disponível no servidor da comunidade MongoDB
Embora a criptografia automática exija o MongoDB Enterprise ou o MongoDB Atlas, a descriptografia automática está disponível nos seguintes produtos do MongoDB:
Servidor MongoDB Community
MongoDB Enterprise Advanced
MongoDB Atlas
Para visualizar um trecho de código que demonstra como ativar a descriptografia automática, selecione a guia correspondente ao seu idioma preferido:
var autoEncryptionOpts = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, bypassAutoEncryption: true, }; var encryptedClient = Mongo( connectionString, autoEncryptionOpts );
var clientSettings = MongoClientSettings.FromConnectionString(connectionString); var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, bypassAutoEncryption: true); clientSettings.AutoEncryptionOptions = autoEncryptionOptions; var client = new MongoClient(clientSettings);
autoEncryptionOpts := options.AutoEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(KeyVaultNamespace). SetBypassAutoEncryption(true) client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI).SetAutoEncryptionOptions(autoEncryptionOpts)) if err != nil { return fmt.Errorf("Connect error for encrypted client: %v", err) } defer func() { _ = client.Disconnect(context.TODO()) }()
MongoClientSettings clientSettings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .autoEncryptionSettings(AutoEncryptionSettings.builder() .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders).bypassAutoEncryption(true) .build()) .build(); MongoClient mongoClient = MongoClients.create(clientSettings);
const client = new MongoClient(connectionString, { useNewUrlParser: true, useUnifiedTopology: true, monitorCommands: true, autoEncryption: { keyVaultNamespace, kmsProviders, bypassAutoEncryption: true, }, });
auto_encryption_opts = AutoEncryptionOpts( kms_providers=kms_providers, key_vault_namespace=key_vault_namespace, bypass_auto_encryption=True, ) client = MongoClient(auto_encryption_opts=auto_encryption_opts)
Exemplo
Suponha que você deseja inserir documentos com a seguinte estrutura em sua instância MongoDB:
{ "name": "<name of person>", "age": <age of person>, "favorite-foods": ["<array of foods>"] }
Criar uma instância do MongoClient
Neste exemplo, você usa a mesma instância do MongoClient
para acessar sua coleção do Key Vault e ler e gravar dados criptografados.
Os trechos de código a seguir mostram como criar uma instância MongoClient
:
const autoEncryptionOpts = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }; const encryptedClient = Mongo(connectionString, autoEncryptionOpts);
var client = new MongoClient(connectionString);
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI)) if err != nil { panic(fmt.Errorf("Client connect error %v", err)) }
MongoClient client = MongoClients.create(connectionString);
const client = new MongoClient(connectionString, { useNewUrlParser: true, useUnifiedTopology: true, });
client = MongoClient(your_connection_uri)
Criar uma Instância do ClientEncryption
Os trechos de código a seguir mostram como criar uma instância ClientEncryption
:
const clientEncryption = encryptedClient.getClientEncryption();
var collection = client.GetDatabase(db).GetCollection<BsonDocument>(coll); var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: client, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders); var clientEncryption = new ClientEncryption(clientEncryptionOptions);
coll := client.Database(DbName).Collection(CollName) clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(KeyVaultNamespace).SetKmsProviders(kmsProviders) clientEnc, err := mongo.NewClientEncryption(client, clientEncryptionOpts) if err != nil { panic(fmt.Errorf("NewClientEncryption error %v", err)) } defer func() { _ = clientEnc.Close(context.TODO()) }()
MongoCollection<Document> collection = client.getDatabase(db).getCollection(coll); ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
const collection = client.db(db).collection(coll); const encryption = new ClientEncryption(client, { keyVaultNamespace, kmsProviders, });
coll = client.employees.foods client_encryption = ClientEncryption( kms_providers, "encryption.___keyVault", client, coll.codec_options, )
Observação
CodecOptions
O driver Python para MongoDB requer que você indique o CodecOptions
usado para criptografar e descriptografar seus documentos.
Especifique o CodecOptions
que você configurou no MongoClient
, Database
ou Collection
com o qual está gravando dados criptografados e descriptografados do aplicativo no MongoDB.
Criptografar campos e inserir
Você deseja criptografar os campos do documento usando os seguintes algoritmos:
Nome do campo | Algoritmo de criptografia | Tipo de campo BSON |
---|---|---|
name | Determinístico(a) | String |
age | Sem criptografia | Int |
favorite-foods | Aleatório | Array |
Os seguintes trechos de código mostram como criptografar manualmente os campos em seu documento e inserir seu documento no MongoDB:
Observação
A variável dataKeyId
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
const encName = clientEncryption.encrypt( dataKeyId, "Greg", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" ); const encFoods = clientEncryption.encrypt( dataKeyId, ["Cheese", "Grapes"], "AEAD_AES_256_CBC_HMAC_SHA_512-Random" ); db.getSiblingDB(database).getCollection(collection).insertOne({ name: encName, foods: encFoods, });
Observação
A variável dataKeyId
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
var encryptedName = clientEncryption.Encrypt( "Greg", new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId), CancellationToken.None); var encryptedFoods = clientEncryption.Encrypt( new BsonArray { "Cheese", "Grapes" }, new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random", keyId: dataKeyId), CancellationToken.None); collection.InsertOne(new BsonDocument { { "name", encryptedName }, { "age", 83 }, { "foods", encryptedFoods } });
Observação
A variável dataKeyId
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
nameRawValueType, nameRawValueData, err := bson.MarshalValue("Greg") if err != nil { panic(err) } nameRawValue := bson.RawValue{Type: nameRawValueType, Value: nameRawValueData} nameEncryptionOpts := options.Encrypt(). SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"). SetKeyID(dataKeyId) nameEncryptedField, err := clientEnc.Encrypt( context.TODO(), nameRawValue, nameEncryptionOpts) if err != nil { panic(err) } foodsRawValueType, foodsRawValueData, err := bson.MarshalValue(bson.A{"Grapes", "Cheese"}) if err != nil { panic(err) } foodsRawValue := bson.RawValue{Type: foodsRawValueType, Value: foodsRawValueData} encryptionOpts := options.Encrypt(). SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Random"). SetKeyID(dataKeyId) foodsEncryptedField, err := clientEnc.Encrypt( context.TODO(), foodsRawValue, encryptionOpts) if err != nil { panic(err) } _, err = coll.InsertOne( context.TODO(), bson.D{{"name", nameEncryptedField}, {"foods", foodsEncryptedField}, {"age", 83}}) if err != nil { panic(err) }
Observação
A variável dataKeyId
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
BsonBinary encryptedName = clientEncryption.encrypt(new BsonString("Greg"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId)); BsonBinary encryptedFoods = clientEncryption.encrypt(new BsonArray().parse("[\"Grapes\", \"Foods\"]"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Random").keyId(dataKeyId)); collection.insertOne(new Document("name", encryptedName).append("foods", encryptedFoods).append("age", 83));
Observação
A variável dataKeyId
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
encryptedName = await encryption.encrypt("Greg", { algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId, }); encryptedFoods = await encryption.encrypt(["Cheese", "Grapes"], { algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random", keyId: dataKeyId, }); await collection.insertOne({ name: encryptedName, age: 83, foods: encryptedFoods, });
Observação
A variável data_key_id
nos exemplos abaixo refere-se a uma chave de encriptação de dados (DEK). Para saber como gerar uma DEK com seu fornecedor de chave local, consulte o Início rápido. Para saber como criar uma DEK com um sistema de gerenciamento de chaves específico, consulte Tutoriais.
encrypted_name = client_encryption.encrypt( "Greg", Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_id=data_key_id, ) encrypted_foods = client_encryption.encrypt( ["Cheese", "Grapes"], Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Random, key_id=data_key_id, ) coll.insert_one({"name": encrypted_name, "age": 83, "foods": encrypted_foods})
Recuperar documento e descriptografar campos
Os seguintes trechos de código mostram como recuperar seu documento inserido e descriptografar manualmente os campos criptografados:
const encNameQuery = clientEncryption.encrypt( dataKeyId, "Greg", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" ); let doc = db.getSiblingDB(database).getCollection(collection).findOne({ name: encNameQuery, }); console.log(doc); doc.name = clientEncryption.decrypt(doc.name); doc.foods = clientEncryption.decrypt(doc.foods); console.log(doc);
var nameToQuery = "Greg"; var encryptedNameToQuery = clientEncryption.Encrypt( nameToQuery, new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId), CancellationToken.None); var doc = collection.Find(new BsonDocument { { "name", encryptedNameToQuery } }).Single(); Console.WriteLine($"Encrypted document: {doc}"); doc["name"] = clientEncryption.Decrypt(doc["name"].AsBsonBinaryData, CancellationToken.None); doc["foods"] = clientEncryption.Decrypt(doc["foods"].AsBsonBinaryData, CancellationToken.None); Console.WriteLine($"Decrypted field: {doc}");
nameQueryRawValueType, nameQueryRawValueData, err := bson.MarshalValue("Greg") if err != nil { panic(err) } nameQueryRawValue := bson.RawValue{Type: nameQueryRawValueType, Value: nameQueryRawValueData} nameQueryEncryptionOpts := options.Encrypt(). SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"). SetKeyID(dataKeyId) nameQueryEncryptedField, err := clientEnc.Encrypt( context.TODO(), nameQueryRawValue, nameQueryEncryptionOpts) if err != nil { panic(err) } var result bson.M err = coll.FindOne( context.TODO(), bson.D{{"name", nameQueryEncryptedField}}).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { return } panic(err) } fmt.Printf("Encrypted Document: %s\n", result) nameDecrypted, err := clientEnc.Decrypt( context.TODO(), result["name"].(primitive.Binary)) foodsDecrypted, err := clientEnc.Decrypt( context.TODO(), result["foods"].(primitive.Binary)) result["foods"] = foodsDecrypted result["name"] = nameDecrypted fmt.Printf("Decrypted Document: %s\n", result)
BsonBinary encryptedNameQuery = clientEncryption.encrypt(new BsonString("Greg"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId)); Document result = collection.find(eq("name", encryptedNameQuery)).first(); System.out.println("Encrypted Document: " + result.toJson()); result.replace("name", clientEncryption.decrypt(new BsonBinary(result.get("name", Binary.class).getData()))); result.replace("foods", clientEncryption.decrypt(new BsonBinary(result.get("foods", Binary.class).getData()))); System.out.println("Decrypted Document: " + result.toJson());
queryEncryptedName = await encryption.encrypt("Greg", { algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId, }); let doc = await collection.findOne({ name: queryEncryptedName }); console.log("Encrypted Document: ", doc); doc.name = encryption.decrypt(doc.name); doc.foods = encryption.decrypt(doc.foods); console.log("Decrypted document: ", doc);
name_to_query = "Greg" encrypted_name_to_query = client_encryption.encrypt( name_to_query, Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_id=data_key_id, ) doc = client.employees.foods.find_one({"name": encrypted_name_to_query}) print("Encrypted document: %s" % (doc,)) doc["name"] = client_encryption.decrypt(doc["name"]) doc["foods"] = client_encryption.decrypt(doc["foods"]) print("Decrypted document: %s" % (doc,))
Aplicação de criptografia em nível de campo no lado do servidor
O MongoDB suporta o uso da validação de esquema para impor a criptografia de campos específicos em uma coleção.
Um cliente que executa a criptografia de nível de campo do lado do cliente com o mecanismo de criptografia explícito em uma instância do MongoDB configurada para impor a criptografia de determinados campos deve criptografar esses campos conforme especificado na instância do MongoDB.
Saiba mais
Para saber mais sobre coleções de Key Vault, chaves de criptografia de dados e chaves mestras de clientes, consulte Chaves e Key Vaults.
Para saber mais sobre os provedores KMS e os objetos kmsProviders
, consulte Provedores CSFLE KMS.