La encriptación en uso ofrece dos funcionalidades que encriptan datos sensibles en tus colecciones de MongoDB:
Cifrado a nivel de campo en el lado del cliente - Cifra campos de datos específicos en el lado del cliente
Queryable Encryption - Cifra los datos manteniendo la capacidad de consultar los campos cifrados
Ambas funciones garantizan que partes no autorizadas, incluidos los administradores del servidor, no puedan leer datos cifrados.
Instalación
Debes instalar libmongocrypt Como dependencia para usar el cifrado en uso. Consulte las instrucciones de instalación de libmongocrypt en el manual del servidor MongoDB para obtener una guía de instalación completa.
Después de instalar libmongocrypt, configura el controlador C con -DENABLE_CLIENT_SIDE_ENCRYPTION=ON para activar el cifrado en uso, como se muestra en el siguiente ejemplo:
$ cd mongo-c-driver $ mkdir cmake-build && cd cmake-build $ cmake -DENABLE_CLIENT_SIDE_ENCRYPTION=ON .. $ cmake --build . --target install
Query Analysis
Para respaldar el cifrado automático, necesita una de las siguientes dependencias:
El ejecutable
mongocryptd. Consulta la guía mongocryptd en el manual del MongoDB Server para obtener instrucciones de instalación.La
crypt_sharedbiblioteca. Consulte la guía de la biblioteca compartida de cifrado automático en el manual del servidor MongoDB para obtener más información.
Un mongoc_client_t o mongoc_client_pool_t configurado con cifrado automático intenta cargar automáticamente la crypt_shared biblioteca. Si crypt_shared falla la carga de la biblioteca, mongoc_client_t o mongoc_client_pool_t intenta generar el mongocryptd proceso desde el de la PATH aplicación. Para configurar el uso de crypt_shared y,mongocryptd consulte mongoc_auto_encryption_opts_set_extra.
API
Use mongoc_client_encryption_t para el cifrado explícito y la gestión de claves. Utiliza mongoc_client_enable_auto_encryption y mongoc_client_pool_enable_auto_encryption para habilitar el cifrado automático.
Las funcionalidades de Queryable Encryption (QE) y Client-Side Field Level Encryption (CSFLE) comparten gran parte de la misma API, con algunas excepciones:
Los algoritmos compatibles documentados en mongoc_client_encryption_encrypt_opts_set_algorithm no se aplican a ambas funcionalidades.
mongoc_auto_encryption_opts_set_encrypted_fields_map se aplica sólo a Queryable Encryption.
mongoc_auto_encryption_opts_set_schema_map solo se aplica a CSFLE.
Encriptación a nivel de campo
CSFLE permite a los administradores y desarrolladores cifrar campos de datos específicos además de otras funciones de cifrado de MongoDB.
Mediante el uso de CSFLE, es posible cifrar campos del lado del cliente sin necesidad de ninguna configuración o directiva del lado del servidor. CSFLE admite cargas de trabajo en las que las aplicaciones deben garantizar que las partes no autorizadas, incluidos los administradores de servidores, no puedan leer datos cifrados.
El cifrado automático, donde los campos sensibles en los comandos se cifran automáticamente, requiere una dependencia exclusiva de Enterprise para query Analysis. Consulta Análisis de Consultas para más información.
Tip
Cifrado automático a nivel de campo en el lado del cliente
Habilite el cifrado automático llamando a mongoc_client_enable_auto_encryption en un objeto mongoc_client_t. Los siguientes ejemplos muestran cómo configurar el cifrado automático usando mongoc_client_encryption_t para crear una nueva clave de datos de cifrado.
Nota
El cifrado automático requiere MongoDB Enterprise Advanced 4.2 o posterior, o un clúster de MongoDB 4.2 o posterior de Atlas. La versión Community de MongoDB Server admite la descifrado automática y Cifrado explícito.
Proporcionar reglas locales de cifrado automático
Puede especificar reglas de cifrado automático mediante un mapa de esquema. Para crear un mapa de esquema, llame a la función mongoc_auto_encryption_opts_set_schema_map. Las reglas de cifrado automático utilizan un subconjunto estricto de la sintaxis del esquema JSON.
Sumistrar un mapa de esquemas proporciona mayor seguridad que depender de esquemas JSON obtenidos del servidor. Protege contra un servidor malintencionado que anuncia un JSON Schema falso, lo que podría engañar al cliente para que envíe datos sin cifrar que deberían ser cifrado.
Los esquemas JSON proporcionados en el mapa de esquemas solo se aplican a la configuración del cifrado automático. El driver no hace cumplir otras reglas de validación en el JSON schema y se produce un error.
El siguiente ejemplo utiliza la función mongoc_auto_encryption_opts_set_schema_map() para crear un mapa de esquemas que especifica reglas de cifrado automáticas:
// `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; }
Aplicación de cifrado a nivel de campo del lado del servidor
MongoDB Server admite el uso de validación de esquema para aplicar el cifrado de campos específicos en una colección. Esta validación de esquema impide que una aplicación inserte valores no cifrados en cualquier campo marcado con la palabra clave encrypt de JSON Schema.
Para implementar la aplicación del lado del servidor, debes crear tanto una clave de datos de cifrado como una colección configurada con las reglas de validación de esquema JSON adecuadas, como se muestra en el siguiente ejemplo:
// `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; }
Cifrado explícito
Puede usar cifrado explícito para especificar cómo cifrar campos en su documento para cada operación que realice en la base de datos. Debes definir tus propias claves de datos de cifrado y opciones de cifrado cuando utilices cifrado explícito.
El cifrado explícito es una funcionalidad de MongoDB Community Edition y no utiliza Análisis de consultas (mongocryptd o crypt_shared). El cifrado explícito utiliza la clase mongoc_client_encryption_t. El siguiente ejemplo demuestra cómo usar el cifrado y descifrado explícitos:
// `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; }
Cifrado explícito con desencriptado automático
Aunque el cifrado automático requiere MongoDB Enterprise Advanced o un clúster de MongoDB Atlas, todos los productos de MongoDB Server admiten la descifrado automático. Para configurar el cifrado explícito con descifrado automático, establece bypass_auto_encryption=True en mongoc_auto_encryption_opts_t, como se muestra en el siguiente ejemplo:
// `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
Queryable Encryption es la funcionalidad de cifrado de última generación en uso, que se introdujo por primera vez como funcionalidad en vista previa en MongoDB Server versión 6.0 y como funcionalidad generalmente disponible (GA) en MongoDB 7.0. La Queryable Encryption permite buscar la igualdad de los campos cifrados y cifra cada valor de manera única.
Nota
QE requiere que el MongoDB Server sea 7.0 o posterior
Para obtener información sobre cómo actualizar su implementación de MongoDB Server de 6.0 a,7.0 consulte Actualizar 6.0 a.7 0 en el manual de MongoDB Server.
Consulta la Queryable Encryption guía en el manual de MongoDB Server para obtener más información sobre esta funcionalidad.
QE en el servidor MongoDB 6.0
El servidor MongoDB 6.0 introdujo el cifrado consultable como versión preliminar pública. El servidor MongoDB 7.0 incluye cambios radicales en el protocolo de cifrado consultable que afectan la compatibilidad entre las diferentes versiones de las bibliotecas de controladores y el servidor.
La siguiente tabla muestra qué versiones son compatibles para Queryable Encryption:
libmongocrypt | libmongoc | Versiones compatibles del servidor MongoDB |
|---|---|---|
1.7.x y anteriores | 1.23.x y anteriores | Solo 6.0 |
1.8.0 y posteriores | 1.24.0 y posteriores | 7.0 y versiones posteriores |
Importante
Errores de incompatibilidad de versión
El uso de versiones incompatibles de los paquetes enumerados en la tabla anterior provoca errores en el servidor.