El cifrado en uso proporciona dos funciones que cifran datos confidenciales en sus colecciones de MongoDB:
Cifrado a nivel de campo del lado del cliente: cifra campos de datos específicos del lado del cliente
Cifrado consultable: cifra los datos manteniendo la capacidad de consultar campos cifrados.
Ambas funciones garantizan que partes no autorizadas, incluidos los administradores del servidor, no puedan leer datos cifrados.
Instalación
Debes instalarlo 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, configure el controlador C con -DENABLE_CLIENT_SIDE_ENCRYPTION=ON para habilitar 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
Análisis de consultas
Para admitir el cifrado automático, necesita una de las siguientes dependencias:
El
mongocryptdejecutable. Consulte la guía de mongocryptd en el manual del servidor MongoDB 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
Utilice mongoc_client_encryption_t para el cifrado explícito y la gestión de claves. Utilice mongoc_client_enable_auto_encryption y mongoc_client_pool_enable_auto_encryption para habilitar el cifrado automático.
Las funciones de cifrado consultable (QE) y cifrado a nivel de campo del lado del cliente (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 funciones.
mongoc_auto_encryption_opts_set_encrypted_fields_map solo se aplica al cifrado consultable.
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.
Con CSFLE, puede cifrar campos en el lado del cliente sin necesidad de configuración ni directivas del lado del servidor. CSFLE admite cargas de trabajo donde las aplicaciones deben garantizar que terceros no autorizados, incluidos los administradores del servidor, no puedan leer los datos cifrados.
El cifrado automático, donde los campos confidenciales de los comandos se cifran automáticamente, requiere una dependencia exclusiva de Enterprise para el análisis de consultas.Consulte Análisis de consultas para obtener 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 4.2 Atlas de MongoDB o posterior. La versión comunitaria de MongoDB Server admite el descifrado automático y el cifrado explícito.
Proporcionar reglas de cifrado automático local
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 controlador no aplica otras reglas de validación del esquema JSON y generan un error.
El siguiente ejemplo utiliza la función mongoc_auto_encryption_opts_set_schema_map() para crear un mapa de esquema que especifica reglas de cifrado automático:
// `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 del cifrado a nivel de campo del lado del servidor
MongoDB Server admite la validación de esquemas para aplicar el cifrado a campos específicos de una colección. Esta validación impide que una aplicación inserte valores sin cifrar en los campos marcados con la palabra clave encrypt del esquema JSON.
Para implementar la aplicación del lado del servidor, debe crear una clave de datos de cifrado y una colección configurada con las reglas de validación del 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 el cifrado explícito para especificar cómo cifrar los campos de su documento para cada operación que realice en la base de datos. Debe definir sus propias claves de datos de cifrado y opciones de cifrado al usar el cifrado explícito.
El cifrado explícito es una función de MongoDB Community Edition y no utiliza el análisis de consultas (mongocryptd crypt_sharedni). Utiliza la clase mongoc_client_encryption_t. El siguiente ejemplo muestra cómo usar el cifrado y el 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 MongoDB Server admiten el descifrado automático. Para configurar el cifrado explícito con descifrado automático, configure 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
El cifrado consultable es la función de cifrado en uso de próxima generación, introducida inicialmente como versión preliminar en MongoDB Server 6.0 y como función de disponibilidad general (GA) en MongoDB 7.0. El cifrado consultable permite buscar la igualdad en los campos cifrados y cifra cada valor de forma única.
Nota
QE requiere MongoDB Server 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.
Consulte la guía de cifrado consultable en el manual del servidor MongoDB para obtener más información sobre esta función.
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 con el cifrado consultable:
libmongocrypt | libmongoc | Versiones compatibles del servidor MongoDB |
|---|---|---|
1.7.x y anteriores | 1.23.x y anteriores | 6.0 solamente |
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 genera errores en el servidor.