A criptografia em execução oferece duas funcionalidades que criptografam dados confidenciais em suas collections do MongoDB :
Criptografia nonível do campo do lado do cliente - Criptografa campos de dados específicos do lado do cliente
Queryable Encryption - Criptografa dados enquanto mantém a capacidade de consultar campos criptografados
Ambos os recursos garantem que partes não autorizadas, incluindo administradores de servidor , não possam ler dados criptografados.
Instalação
Você deve instalar o libmongocrypt como uma dependência para usar a criptografia em execução. Consulte as instruções de instalação da libmongocrypt no manual do MongoDB Server para obter um guia de instalação completo.
Após instalar o libmongocrypt, configure o driver C com -DENABLE_CLIENT_SIDE_ENCRYPTION=ON para habilitar a criptografia em execução, conforme mostrado no exemplo a seguir:
$ cd mongo-c-driver $ mkdir cmake-build && cd cmake-build $ cmake -DENABLE_CLIENT_SIDE_ENCRYPTION=ON .. $ cmake --build . --target install
Análise de Query
Para oferecer suporte à criptografia automática, você precisa de uma das seguintes dependências:
O
mongocryptdexecutável. Consulte o guia mongocryptd no manual do MongoDB Server para obter instruções de instalação.A
crypt_sharedbiblioteca. Consulte o guia Biblioteca compartilhada de criptografia automática no manual do MongoDB Server para obter mais informações.
Um mongoc_client_t ou mongoc_client_pool_t configurado com criptografia automática tenta carregar automaticamente a crypt_shared biblioteca. Se o carregamento da crypt_shared biblioteca falhar, o mongoc_client_t ou mongoc_client_pool_t tentará gerar o mongocryptd processo a partir do do PATH aplicativo. Para configurar o uso de crypt_shared e,mongocryptd consulte mongoc_auto_encryption_opts_set_extra.
API
Use mongoc_client_encryption_t para criptografia explícita e gerenciamento de chaves. Use mongoc_client_enable_auto_encryption e mongoc_client_pool_enable_auto_encryption para ativar a criptografia automática.
Os recursos Queryable Encryption (QE) e Client-Side Field Level Encryption (CSFLE) compartilham grande parte da mesma API, com algumas exceções:
Os algoritmos suportados documentados em mongoc_client_encryption_encrypt_opts_set_algorithm não se aplicam a ambas as funcionalidades.
mongoc_auto_encryption_opts_set_encrypted_fields_map aplica-se apenas ao Queryable Encryption.
mongoc_auto_encryption_opts_set_schema_map aplica-se apenas ao CSFLE.
Criptografia no nível de campo do cliente
O CSFLE permite que administradores e desenvolvedores criptografem campos de dados específicos, além de outros recursos de criptografia MongoDB .
Ao usar o CSFLE, você pode criptografar campos do lado do cliente sem nenhuma configuração ou diretiva do lado do servidor. O CSFLE oferece suporte a cargas de trabalho em que os aplicativos devem garantir que partes não autorizadas, incluindo administradores de servidor , não possam ler dados criptografados.
A criptografia automática, em que campos confidenciais em comandos são criptografados automaticamente, requer uma dependência somente empresarial para a Análise de Query. Consulte Análise de Query para obter mais informações.
Dica
Criptografia automática no nível do campo do lado do cliente
Habilite a criptografia automática chamando mongoc_client_enable_auto_encryption em um objeto mongoc_client_t . Os exemplos a seguir mostram como configurar a criptografia automática usando mongoc_client_encryption_t para criar uma nova chave de dados de criptografia.
Observação
A criptografia automática requer Enterprise Advanced 4.2 ou posterior, ou um MongoDB 4.2 ou Atlas cluster posterior. A versão da comunidade do MongoDB Server suporta descriptografia automática e criptografia explícita.
Fornecimento de regras de criptografia automática local
Você pode especificar regras de criptografia automática usando um mapa de esquema. Para criar um mapa de esquema, chame a função mongoc_auto_encryption_opts_set_schema_map. As regras de criptografia automática usam um subconjunto rigoroso da sintaxe do JSON schema.
Fornecer um mapa de esquema oferece mais segurança do que confiar nos JSON schemas obtidos do servidor. Ele protege contra um servidor malicioso que anuncia um falso JSON schema, que pode induzir o cliente a enviar dados não criptografados que devem ser criptografados.
Os JSON schemas fornecidos no mapa de esquema se aplicam somente à configuração da criptografia automática. Outras regras de validação no JSON schema não são aplicadas pelo driver e resultam em um erro.
O exemplo seguinte utiliza a função mongoc_auto_encryption_opts_set_schema_map() para criar um mapa de esquema que especifica regras de criptografia automática :
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes. int main(void) { bson_error_t error; // The key vault collection stores encrypted data keys: const char *keyvault_db_name = "keyvault"; const char *keyvault_coll_name = "datakeys"; // The encrypted collection stores application data: const char *encrypted_db_name = "db"; const char *encrypted_coll_name = "coll"; // Set `local_key` to a 96 byte base64-encoded string: const char *local_key = "qx/3ydlPRXgUrBvSBWLsllUTaYDcS/pyaVo27qBHkS2AFePjInwhzCmDWHdmCYPmzhO4lRBzeZKFjSafduLL5z5DMvR/" "QFfV4zc7btcVmV3QWbDwqZyn6G+Y18ToLHyK"; const char *uri = "mongodb://localhost/?appname=client-side-encryption"; mongoc_init(); // Configure KMS providers used to encrypt data keys: bson_t kms_providers; { char *as_json = bson_strdup_printf(BSON_STR({"local" : {"key" : "%s"}}), local_key); init_bson(kms_providers, as_json); bson_free(as_json); } // Set up key vault collection: mongoc_client_t *keyvault_client; { keyvault_client = mongoc_client_new(uri); if (!keyvault_client) { FAIL("Failed to create keyvault client"); } mongoc_collection_t *coll = mongoc_client_get_collection(keyvault_client, keyvault_db_name, keyvault_coll_name); mongoc_collection_drop(coll, NULL); // Clear pre-existing data. // Create index to ensure keys have unique keyAltNames: bson_t index_keys, index_opts; init_bson(index_keys, BSON_STR({"keyAltNames" : 1})); init_bson(index_opts, BSON_STR({"unique" : true, "partialFilterExpression" : {"keyAltNames" : {"$exists" : true}}})); mongoc_index_model_t *index_model = mongoc_index_model_new(&index_keys, &index_opts); if (!mongoc_collection_create_indexes_with_opts( coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to create index: %s", error.message); } mongoc_index_model_destroy(index_model); bson_destroy(&index_opts); bson_destroy(&index_keys); mongoc_collection_destroy(coll); } // Create ClientEncryption object: mongoc_client_encryption_t *client_encryption; { mongoc_client_encryption_opts_t *ce_opts = mongoc_client_encryption_opts_new(); mongoc_client_encryption_opts_set_kms_providers(ce_opts, &kms_providers); mongoc_client_encryption_opts_set_keyvault_namespace(ce_opts, keyvault_db_name, keyvault_coll_name); mongoc_client_encryption_opts_set_keyvault_client(ce_opts, keyvault_client); client_encryption = mongoc_client_encryption_new(ce_opts, &error); if (!client_encryption) { FAIL("Failed to create ClientEncryption: %s", error.message); } mongoc_client_encryption_opts_destroy(ce_opts); } // Create data key (see: // https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules): bson_value_t datakey_id; { mongoc_client_encryption_datakey_opts_t *dk_opts = mongoc_client_encryption_datakey_opts_new(); if (!mongoc_client_encryption_create_datakey(client_encryption, "local", dk_opts, &datakey_id, &error)) { FAIL("Failed to create data key: %s", error.message); } mongoc_client_encryption_datakey_opts_destroy(dk_opts); } // Create a schema map: bson_t schema_map = BSON_INITIALIZER; { /* { "db.coll": { "properties" : { "encryptedField" : { "encrypt" : { "keyId" : [ "<key ID>" ], "bsonType" : "string", "algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } }, "bsonType" : "object" } } */ bson_t key_ids = BSON_INITIALIZER; BSON_APPEND_VALUE(&key_ids, "0", &datakey_id); bson_t encrypt = BSON_INITIALIZER; BSON_APPEND_ARRAY(&encrypt, "keyId", &key_ids); BSON_APPEND_UTF8(&encrypt, "bsonType", "string"); BSON_APPEND_UTF8(&encrypt, "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"); bson_t encryptedField = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&encryptedField, "encrypt", &encrypt); bson_t properties = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&properties, "encryptedField", &encryptedField); bson_t db_coll = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&db_coll, "properties", &properties); BSON_APPEND_UTF8(&db_coll, "bsonType", "object"); BSON_APPEND_DOCUMENT(&schema_map, "db.coll", &db_coll); bson_destroy(&key_ids); bson_destroy(&db_coll); bson_destroy(&encrypt); bson_destroy(&encryptedField); bson_destroy(&properties); } // Create client configured to automatically encrypt: mongoc_client_t *encrypted_client; { encrypted_client = mongoc_client_new(uri); if (!encrypted_client) { FAIL("Failed to create client"); } mongoc_auto_encryption_opts_t *ae_opts = mongoc_auto_encryption_opts_new(); mongoc_auto_encryption_opts_set_schema_map(ae_opts, &schema_map); mongoc_auto_encryption_opts_set_keyvault_namespace(ae_opts, keyvault_db_name, keyvault_coll_name); mongoc_auto_encryption_opts_set_kms_providers(ae_opts, &kms_providers); if (!mongoc_client_enable_auto_encryption(encrypted_client, ae_opts, &error)) { FAIL("Failed to enable auto encryption: %s", error.message); } mongoc_auto_encryption_opts_destroy(ae_opts); } // Insert a document: mongoc_collection_t *encrypted_coll = mongoc_client_get_collection(encrypted_client, encrypted_db_name, encrypted_coll_name); { mongoc_collection_drop(encrypted_coll, NULL); // Clear pre-existing data. bson_t to_insert = BSON_INITIALIZER; BSON_APPEND_UTF8(&to_insert, "encryptedField", "foobar"); if (!mongoc_collection_insert_one(encrypted_coll, &to_insert, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to insert: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(&to_insert, NULL); printf("Inserted document with automatic encryption: %s\n", as_str); bson_free(as_str); bson_destroy(&to_insert); } // Retrieve document with automatic decryption: { bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(encrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document with automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); } // Retrieve document without decryption: { mongoc_collection_t *unencrypted_coll = mongoc_client_get_collection(keyvault_client, encrypted_db_name, encrypted_coll_name); bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(unencrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document without automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); mongoc_collection_destroy(unencrypted_coll); } mongoc_collection_destroy(encrypted_coll); mongoc_client_destroy(encrypted_client); bson_destroy(&schema_map); bson_value_destroy(&datakey_id); mongoc_client_encryption_destroy(client_encryption); bson_destroy(&kms_providers); mongoc_client_destroy(keyvault_client); mongoc_cleanup(); return 0; }
Aplicação de criptografia em nível de campo no lado do servidor
O MongoDB Server suporta o uso de validação de esquema para impor a criptografia de campos específicos em uma coleção. Essa validação de esquema impede que um aplicação insira valores não criptografados em quaisquer campos marcados com a palavra-chave encrypt JSON schema.
Para implementar a imposição do lado do servidor, você deve criar uma chave de dados de criptografia e uma coleção configurada com as regras de validação apropriadas do JSON schema, como mostrado no exemplo a seguir:
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes. int main(void) { bson_error_t error; // The key vault collection stores encrypted data keys: const char *keyvault_db_name = "keyvault"; const char *keyvault_coll_name = "datakeys"; // The encrypted collection stores application data: const char *encrypted_db_name = "db"; const char *encrypted_coll_name = "coll"; // Set `local_key` to a 96 byte base64-encoded string: const char *local_key = "qx/3ydlPRXgUrBvSBWLsllUTaYDcS/pyaVo27qBHkS2AFePjInwhzCmDWHdmCYPmzhO4lRBzeZKFjSafduLL5z5DMvR/" "QFfV4zc7btcVmV3QWbDwqZyn6G+Y18ToLHyK"; const char *uri = "mongodb://localhost/?appname=client-side-encryption"; mongoc_init(); // Configure KMS providers used to encrypt data keys: bson_t kms_providers; { char *as_json = bson_strdup_printf(BSON_STR({"local" : {"key" : "%s"}}), local_key); init_bson(kms_providers, as_json); bson_free(as_json); } // Set up key vault collection: mongoc_client_t *keyvault_client; { keyvault_client = mongoc_client_new(uri); if (!keyvault_client) { FAIL("Failed to create keyvault client"); } mongoc_collection_t *coll = mongoc_client_get_collection(keyvault_client, keyvault_db_name, keyvault_coll_name); mongoc_collection_drop(coll, NULL); // Clear pre-existing data. // Create index to ensure keys have unique keyAltNames: bson_t index_keys, index_opts; init_bson(index_keys, BSON_STR({"keyAltNames" : 1})); init_bson(index_opts, BSON_STR({"unique" : true, "partialFilterExpression" : {"keyAltNames" : {"$exists" : true}}})); mongoc_index_model_t *index_model = mongoc_index_model_new(&index_keys, &index_opts); if (!mongoc_collection_create_indexes_with_opts( coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to create index: %s", error.message); } mongoc_index_model_destroy(index_model); bson_destroy(&index_opts); bson_destroy(&index_keys); mongoc_collection_destroy(coll); } // Create ClientEncryption object: mongoc_client_encryption_t *client_encryption; { mongoc_client_encryption_opts_t *ce_opts = mongoc_client_encryption_opts_new(); mongoc_client_encryption_opts_set_kms_providers(ce_opts, &kms_providers); mongoc_client_encryption_opts_set_keyvault_namespace(ce_opts, keyvault_db_name, keyvault_coll_name); mongoc_client_encryption_opts_set_keyvault_client(ce_opts, keyvault_client); client_encryption = mongoc_client_encryption_new(ce_opts, &error); if (!client_encryption) { FAIL("Failed to create ClientEncryption: %s", error.message); } mongoc_client_encryption_opts_destroy(ce_opts); } // Create data key (see: // https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules): bson_value_t datakey_id; { mongoc_client_encryption_datakey_opts_t *dk_opts = mongoc_client_encryption_datakey_opts_new(); if (!mongoc_client_encryption_create_datakey(client_encryption, "local", dk_opts, &datakey_id, &error)) { FAIL("Failed to create data key: %s", error.message); } mongoc_client_encryption_datakey_opts_destroy(dk_opts); } // Create collection with remote schema: bson_t schema = BSON_INITIALIZER; { /* { "properties" : { "encryptedField" : { "encrypt" : { "keyId" : [ "<key ID>" ], "bsonType" : "string", "algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } }, "bsonType" : "object" } */ bson_t key_ids = BSON_INITIALIZER; BSON_APPEND_VALUE(&key_ids, "0", &datakey_id); bson_t encrypt = BSON_INITIALIZER; BSON_APPEND_ARRAY(&encrypt, "keyId", &key_ids); BSON_APPEND_UTF8(&encrypt, "bsonType", "string"); BSON_APPEND_UTF8(&encrypt, "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"); bson_t encryptedField = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&encryptedField, "encrypt", &encrypt); bson_t properties = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&properties, "encryptedField", &encryptedField); BSON_APPEND_DOCUMENT(&schema, "properties", &properties); BSON_APPEND_UTF8(&schema, "bsonType", "object"); bson_destroy(&key_ids); bson_destroy(&encrypt); bson_destroy(&encryptedField); bson_destroy(&properties); } // Create client configured to automatically encrypt: mongoc_client_t *encrypted_client; { encrypted_client = mongoc_client_new(uri); if (!encrypted_client) { FAIL("Failed to create client"); } mongoc_auto_encryption_opts_t *ae_opts = mongoc_auto_encryption_opts_new(); mongoc_auto_encryption_opts_set_keyvault_namespace(ae_opts, keyvault_db_name, keyvault_coll_name); mongoc_auto_encryption_opts_set_kms_providers(ae_opts, &kms_providers); if (!mongoc_client_enable_auto_encryption(encrypted_client, ae_opts, &error)) { FAIL("Failed to enable auto encryption: %s", error.message); } mongoc_auto_encryption_opts_destroy(ae_opts); } // Clear pre-existing data: { mongoc_collection_t *coll = mongoc_client_get_collection(encrypted_client, encrypted_db_name, encrypted_coll_name); mongoc_collection_drop(coll, NULL); mongoc_collection_destroy(coll); } // Create collection with server-side schema: mongoc_collection_t *encrypted_coll; { mongoc_database_t *db = mongoc_client_get_database(encrypted_client, encrypted_db_name); bson_t create_opts = BSON_INITIALIZER; // { validator: { $jsonSchema: <schema> } } bson_t json_schema = BSON_INITIALIZER; BSON_APPEND_DOCUMENT(&json_schema, "$jsonSchema", &schema); BSON_APPEND_DOCUMENT(&create_opts, "validator", &json_schema); encrypted_coll = mongoc_database_create_collection(db, encrypted_coll_name, &create_opts, &error); if (!encrypted_coll) { FAIL("Failed to create collection: %s", error.message); } bson_destroy(&json_schema); bson_destroy(&create_opts); mongoc_database_destroy(db); } // Insert a document: { bson_t to_insert = BSON_INITIALIZER; BSON_APPEND_UTF8(&to_insert, "encryptedField", "foobar"); if (!mongoc_collection_insert_one(encrypted_coll, &to_insert, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to insert: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(&to_insert, NULL); printf("Inserted document with automatic encryption: %s\n", as_str); bson_free(as_str); bson_destroy(&to_insert); } // Retrieve document with automatic decryption: { bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(encrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document with automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); } // Retrieve document without automatic decryption: { mongoc_collection_t *unencrypted_coll = mongoc_client_get_collection(keyvault_client, encrypted_db_name, encrypted_coll_name); bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(unencrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document without automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); mongoc_collection_destroy(unencrypted_coll); } mongoc_collection_destroy(encrypted_coll); bson_value_destroy(&datakey_id); mongoc_client_destroy(encrypted_client); bson_destroy(&schema); mongoc_client_encryption_destroy(client_encryption); bson_destroy(&kms_providers); mongoc_client_destroy(keyvault_client); mongoc_cleanup(); return 0; }
Criptografia explícita
Você pode usar a criptografia explícita para especificar como criptografar campos em seu documento para cada operação executada no banco de dados. Você deve definir suas próprias chaves de dados de criptografia e opções de criptografia ao usar a criptografia explícita.
A criptografia explícita é um recurso do MongoDB Community Edition e não usa Análise de Query (mongocryptd crypt_sharedou). A criptografia explícita usa a classe mongoc_client_encryption_t . O exemplo a seguir demonstra como usar criptografia explícita :
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes. int main(void) { bson_error_t error; // The key vault collection stores encrypted data keys: const char *keyvault_db_name = "keyvault"; const char *keyvault_coll_name = "datakeys"; // Set `local_key` to a 96 byte base64-encoded string: const char *local_key = "qx/3ydlPRXgUrBvSBWLsllUTaYDcS/pyaVo27qBHkS2AFePjInwhzCmDWHdmCYPmzhO4lRBzeZKFjSafduLL5z5DMvR/" "QFfV4zc7btcVmV3QWbDwqZyn6G+Y18ToLHyK"; const char *uri = "mongodb://localhost/?appname=client-side-encryption"; mongoc_init(); // Create client: mongoc_client_t *client = mongoc_client_new(uri); if (!client) { FAIL("Failed to create client"); } // Configure KMS providers used to encrypt data keys: bson_t kms_providers; { char *as_json = bson_strdup_printf(BSON_STR({"local" : {"key" : "%s"}}), local_key); init_bson(kms_providers, as_json); bson_free(as_json); } // Set up key vault collection: { mongoc_collection_t *coll = mongoc_client_get_collection(client, keyvault_db_name, keyvault_coll_name); mongoc_collection_drop(coll, NULL); // Clear pre-existing data. // Create index to ensure keys have unique keyAltNames: bson_t index_keys, index_opts; init_bson(index_keys, BSON_STR({"keyAltNames" : 1})); init_bson(index_opts, BSON_STR({"unique" : true, "partialFilterExpression" : {"keyAltNames" : {"$exists" : true}}})); mongoc_index_model_t *index_model = mongoc_index_model_new(&index_keys, &index_opts); if (!mongoc_collection_create_indexes_with_opts( coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to create index: %s", error.message); } mongoc_index_model_destroy(index_model); bson_destroy(&index_opts); bson_destroy(&index_keys); mongoc_collection_destroy(coll); } // Create ClientEncryption object: mongoc_client_encryption_t *client_encryption; { mongoc_client_encryption_opts_t *ce_opts = mongoc_client_encryption_opts_new(); mongoc_client_encryption_opts_set_kms_providers(ce_opts, &kms_providers); mongoc_client_encryption_opts_set_keyvault_namespace(ce_opts, keyvault_db_name, keyvault_coll_name); mongoc_client_encryption_opts_set_keyvault_client(ce_opts, client); client_encryption = mongoc_client_encryption_new(ce_opts, &error); if (!client_encryption) { FAIL("Failed to create ClientEncryption: %s", error.message); } mongoc_client_encryption_opts_destroy(ce_opts); } // Create data key (see: // https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules): bson_value_t datakey_id; { mongoc_client_encryption_datakey_opts_t *dk_opts = mongoc_client_encryption_datakey_opts_new(); if (!mongoc_client_encryption_create_datakey(client_encryption, "local", dk_opts, &datakey_id, &error)) { FAIL("Failed to create data key: %s", error.message); } mongoc_client_encryption_datakey_opts_destroy(dk_opts); } // Explicitly encrypt a value: bson_value_t encrypted_value; { mongoc_client_encryption_encrypt_opts_t *e_opts = mongoc_client_encryption_encrypt_opts_new(); mongoc_client_encryption_encrypt_opts_set_algorithm(e_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC); mongoc_client_encryption_encrypt_opts_set_keyid(e_opts, &datakey_id); bson_value_t to_encrypt = {.value_type = BSON_TYPE_INT32, .value = {.v_int32 = 123}}; if (!mongoc_client_encryption_encrypt(client_encryption, &to_encrypt, e_opts, &encrypted_value, &error)) { FAIL("Failed to encrypt field: %s", error.message); } mongoc_client_encryption_encrypt_opts_destroy(e_opts); } // Explicitly decrypt a value: { bson_value_t decrypted_value; if (!mongoc_client_encryption_decrypt(client_encryption, &encrypted_value, &decrypted_value, &error)) { FAIL("Failed to decrypt field: %s", error.message); } printf("Decrypted value: %" PRId32 "\n", decrypted_value.value.v_int32); bson_value_destroy(&decrypted_value); } bson_value_destroy(&encrypted_value); bson_value_destroy(&datakey_id); mongoc_client_encryption_destroy(client_encryption); bson_destroy(&kms_providers); mongoc_client_destroy(client); mongoc_cleanup(); return 0; }
Criptografia explícita com descriptografia automática
Embora a criptografia automática exija um Enterprise Advanced ou um cluster do MongoDB Atlas , todos os produtos MongoDB Server oferecem suporte à descriptografia automática. Para configurar a criptografia explícita com descriptografia automática, defina bypass_auto_encryption=True em mongoc_auto_encryption_opts_t, conforme mostrado no exemplo a seguir:
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes. int main(void) { bson_error_t error; // The key vault collection stores encrypted data keys: const char *keyvault_db_name = "keyvault"; const char *keyvault_coll_name = "datakeys"; // The encrypted collection stores application data: const char *encrypted_db_name = "db"; const char *encrypted_coll_name = "coll"; // Set `local_key` to a 96 byte base64-encoded string: const char *local_key = "qx/3ydlPRXgUrBvSBWLsllUTaYDcS/pyaVo27qBHkS2AFePjInwhzCmDWHdmCYPmzhO4lRBzeZKFjSafduLL5z5DMvR/" "QFfV4zc7btcVmV3QWbDwqZyn6G+Y18ToLHyK"; const char *uri = "mongodb://localhost/?appname=client-side-encryption"; mongoc_init(); // Configure KMS providers used to encrypt data keys: bson_t kms_providers; { char *as_json = bson_strdup_printf(BSON_STR({"local" : {"key" : "%s"}}), local_key); init_bson(kms_providers, as_json); bson_free(as_json); } // Create client configured to automatically decrypt: mongoc_client_t *client; { client = mongoc_client_new(uri); if (!client) { FAIL("Failed to create client"); } mongoc_auto_encryption_opts_t *ae_opts = mongoc_auto_encryption_opts_new(); // Bypass automatic encryption (requires mongocryptd/crypt_shared) but keep automatic decryption: mongoc_auto_encryption_opts_set_bypass_auto_encryption(ae_opts, true); mongoc_auto_encryption_opts_set_keyvault_namespace(ae_opts, keyvault_db_name, keyvault_coll_name); mongoc_auto_encryption_opts_set_kms_providers(ae_opts, &kms_providers); if (!mongoc_client_enable_auto_encryption(client, ae_opts, &error)) { FAIL("Failed to enable auto encryption: %s", error.message); } mongoc_auto_encryption_opts_destroy(ae_opts); } // Set up key vault collection: { mongoc_collection_t *coll = mongoc_client_get_collection(client, keyvault_db_name, keyvault_coll_name); mongoc_collection_drop(coll, NULL); // Clear pre-existing data. // Create index to ensure keys have unique keyAltNames: bson_t index_keys, index_opts; init_bson(index_keys, BSON_STR({"keyAltNames" : 1})); init_bson(index_opts, BSON_STR({"unique" : true, "partialFilterExpression" : {"keyAltNames" : {"$exists" : true}}})); mongoc_index_model_t *index_model = mongoc_index_model_new(&index_keys, &index_opts); if (!mongoc_collection_create_indexes_with_opts( coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to create index: %s", error.message); } mongoc_index_model_destroy(index_model); bson_destroy(&index_opts); bson_destroy(&index_keys); mongoc_collection_destroy(coll); } // Create ClientEncryption object: mongoc_client_encryption_t *client_encryption; { mongoc_client_encryption_opts_t *ce_opts = mongoc_client_encryption_opts_new(); mongoc_client_encryption_opts_set_kms_providers(ce_opts, &kms_providers); mongoc_client_encryption_opts_set_keyvault_namespace(ce_opts, keyvault_db_name, keyvault_coll_name); mongoc_client_encryption_opts_set_keyvault_client(ce_opts, client); client_encryption = mongoc_client_encryption_new(ce_opts, &error); if (!client_encryption) { FAIL("Failed to create ClientEncryption: %s", error.message); } mongoc_client_encryption_opts_destroy(ce_opts); } // Create data key (see: // https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules): bson_value_t datakey_id; { mongoc_client_encryption_datakey_opts_t *dk_opts = mongoc_client_encryption_datakey_opts_new(); if (!mongoc_client_encryption_create_datakey(client_encryption, "local", dk_opts, &datakey_id, &error)) { FAIL("Failed to create data key: %s", error.message); } mongoc_client_encryption_datakey_opts_destroy(dk_opts); } // Explicitly encrypt a value: bson_value_t encrypted_value; { mongoc_client_encryption_encrypt_opts_t *e_opts = mongoc_client_encryption_encrypt_opts_new(); mongoc_client_encryption_encrypt_opts_set_algorithm(e_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC); mongoc_client_encryption_encrypt_opts_set_keyid(e_opts, &datakey_id); bson_value_t to_encrypt = {.value_type = BSON_TYPE_INT32, .value = {.v_int32 = 123}}; if (!mongoc_client_encryption_encrypt(client_encryption, &to_encrypt, e_opts, &encrypted_value, &error)) { FAIL("Failed to encrypt field: %s", error.message); } mongoc_client_encryption_encrypt_opts_destroy(e_opts); } // Insert document with encrypted payload: mongoc_collection_t *encrypted_coll = mongoc_client_get_collection(client, encrypted_db_name, encrypted_coll_name); { mongoc_collection_drop(encrypted_coll, NULL); // Clear pre-existing data. bson_t to_insert = BSON_INITIALIZER; BSON_APPEND_VALUE(&to_insert, "encryptedField", &encrypted_value); if (!mongoc_collection_insert_one(encrypted_coll, &to_insert, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to insert: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(&to_insert, NULL); printf("Inserted document with encrypted payload: %s\n", as_str); bson_free(as_str); bson_destroy(&to_insert); } // Retrieve document (automatically decrypts): { bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(encrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document with automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); } mongoc_collection_destroy(encrypted_coll); bson_value_destroy(&encrypted_value); bson_value_destroy(&datakey_id); mongoc_client_encryption_destroy(client_encryption); bson_destroy(&kms_providers); mongoc_client_destroy(client); mongoc_cleanup(); return 0; }
Queryable Encryption
A Queryable Encryption é o recurso de criptografia em uso da próxima geração, introduzido pela primeira vez como um recurso de pré-visualização no MongoDB Server versão 6.0 e como um recurso geralmente disponível (GA) no MongoDB 7.0. Queryable Encryption oferece suporte à pesquisa de campos criptografados em busca de igualdade e criptografa cada valor de forma exclusiva.
Observação
O QE requer MongoDB Server 7.0 ou posterior
Para obter informações sobre a atualização do sistema do MongoDB Server de 6.0 para,7.0 consulte Atualizar 6.0 7para.0 no manual do MongoDB Server .
Consulte o guia Queryable Encryption no manual do MongoDB Server para obter mais informações sobre o recurso.
QE no MongoDB Server 6.0
O MongoDB Server 6.0 introduziu a Queryable Encryption como uma visualização técnica pública. O MongoDB Server 7.0 inclui alterações de ruptura para trás no protocolo Queryable Encryption que afetam a compatibilidade entre diferentes versões das bibliotecas de drivers e do servidor.
A tabela a seguir mostra quais versões são compatíveis com o Queryable Encryption:
libmongocrypt | libmongoc | Versões compatíveis do MongoDB Server |
|---|---|---|
1.7.x e anterior | 1.23.x e anterior | 6.0 apenas |
1.8.0 e posterior | 1.24.0 e posterior | 7.0 e posterior |
Importante
Erros de incompatibilidade de versão
O uso de versões incompatíveis dos pacotes listados na tabela anterior resulta em erros do servidor .