Docs Menu
Docs Home
/ /

Encriptación a nivel de campo

Nuevo en MongoDB 4.2, el cifrado a nivel de campo del lado del cliente (también conocido como CSFLE) permite a los administradores y desarrolladores cifrar campos de datos específicos además de otras funciones de cifrado de MongoDB.

Con CSFLE, los desarrolladores pueden 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 Cifrado en uso para obtener más información.

Tip

The MongoDB Manual for Client-Side Field Level Encryption

El cifrado automático se habilita llamando a mongoc_client_enable_auto_encryption en un 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 4.2 Enterprise o un clúster MongoDB 4.2 Atlas. La versión comunitaria del servidor admite el descifrado automático y el cifrado explícito.

El siguiente ejemplo muestra cómo especificar reglas de cifrado automático mediante un mapa de esquema definido por mongoc_auto_encryption_opts_set_schema_map. Las reglas de cifrado automático se expresan mediante 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 aplicará otras reglas de validación del esquema JSON y generarán un error:

mapa de esquema de cifrado del lado del cliente.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#include "client-side-encryption-helpers.h"
/* Helper method to create a new data key in the key vault, a schema to use that
* key, and writes the schema to a file for later use. */
static bool
create_schema_file (bson_t *kms_providers,
const char *keyvault_db,
const char *keyvault_coll,
mongoc_client_t *keyvault_client,
bson_error_t *error)
{
mongoc_client_encryption_t *client_encryption = NULL;
mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
bson_value_t datakey_id = {0};
char *keyaltnames[] = {"mongoc_encryption_example_1"};
bson_t *schema = NULL;
char *schema_string = NULL;
size_t schema_string_len;
FILE *outfile = NULL;
bool ret = false;
client_encryption_opts = mongoc_client_encryption_opts_new ();
mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts, kms_providers);
mongoc_client_encryption_opts_set_keyvault_namespace (client_encryption_opts, keyvault_db, keyvault_coll);
mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts, keyvault_client);
client_encryption = mongoc_client_encryption_new (client_encryption_opts, error);
if (!client_encryption) {
goto fail;
}
/* Create a new data key and json schema for the encryptedField.
* https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
*/
datakey_opts = mongoc_client_encryption_datakey_opts_new ();
mongoc_client_encryption_datakey_opts_set_keyaltnames (datakey_opts, keyaltnames, 1);
if (!mongoc_client_encryption_create_datakey (client_encryption, "local", datakey_opts, &datakey_id, error)) {
goto fail;
}
/* Create a schema describing that "encryptedField" is a string encrypted
* with the newly created data key using deterministic encryption. */
schema = BCON_NEW (
"properties",
"{",
"encryptedField",
"{",
"encrypt",
"{",
"keyId",
"[",
BCON_BIN (datakey_id.value.v_binary.subtype, datakey_id.value.v_binary.data, datakey_id.value.v_binary.data_len),
"]",
"bsonType",
"string",
"algorithm",
MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
"}",
"}",
"}",
"bsonType",
"object");
/* Use canonical JSON so that other drivers and tools will be
* able to parse the MongoDB extended JSON file. */
schema_string = bson_as_canonical_extended_json (schema, &schema_string_len);
outfile = fopen ("jsonSchema.json", "w");
if (0 == fwrite (schema_string, sizeof (char), schema_string_len, outfile)) {
fprintf (stderr, "failed to write to file\n");
goto fail;
}
ret = true;
fail:
mongoc_client_encryption_destroy (client_encryption);
mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
mongoc_client_encryption_opts_destroy (client_encryption_opts);
bson_free (schema_string);
bson_destroy (schema);
bson_value_destroy (&datakey_id);
if (outfile) {
fclose (outfile);
}
return ret;
}
/* This example demonstrates how to use automatic encryption with a client-side
* schema map using the enterprise version of MongoDB */
int
main (void)
{
/* The collection used to store the encryption data keys. */
#define KEYVAULT_DB "encryption"
#define KEYVAULT_COLL "__libmongocTestKeyVault"
/* The collection used to store the encrypted documents in this example. */
#define ENCRYPTED_DB "test"
#define ENCRYPTED_COLL "coll"
int exit_status = EXIT_FAILURE;
bool ret;
uint8_t *local_masterkey = NULL;
uint32_t local_masterkey_len;
bson_t *kms_providers = NULL;
bson_error_t error = {0};
bson_t *index_keys = NULL;
bson_t *index_opts = NULL;
mongoc_index_model_t *index_model = NULL;
bson_json_reader_t *reader = NULL;
bson_t schema = BSON_INITIALIZER;
bson_t *schema_map = NULL;
/* The MongoClient used to access the key vault (keyvault_namespace). */
mongoc_client_t *keyvault_client = NULL;
mongoc_collection_t *keyvault_coll = NULL;
mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
mongoc_client_t *client = NULL;
mongoc_collection_t *coll = NULL;
bson_t *to_insert = NULL;
mongoc_client_t *unencrypted_client = NULL;
mongoc_collection_t *unencrypted_coll = NULL;
mongoc_init ();
/* Configure the master key. This must be the same master key that was used
* to create the encryption key. */
local_masterkey = hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
if (!local_masterkey || local_masterkey_len != 96) {
fprintf (stderr,
"Specify LOCAL_MASTERKEY environment variable as a "
"secure random 96 byte hex value.\n");
goto fail;
}
kms_providers = BCON_NEW ("local", "{", "key", BCON_BIN (0, local_masterkey, local_masterkey_len), "}");
/* Set up the key vault for this example. */
keyvault_client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption-keyvault");
BSON_ASSERT (keyvault_client);
keyvault_coll = mongoc_client_get_collection (keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_collection_drop (keyvault_coll, NULL);
/* Create a unique index to ensure that two data keys cannot share the same
* keyAltName. This is recommended practice for the key vault. */
index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
index_opts = BCON_NEW ("unique",
BCON_BOOL (true),
"partialFilterExpression",
"{",
"keyAltNames",
"{",
"$exists",
BCON_BOOL (true),
"}",
"}");
index_model = mongoc_index_model_new (index_keys, index_opts);
ret = mongoc_collection_create_indexes_with_opts (
keyvault_coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
/* Create a new data key and a schema using it for encryption. Save the
* schema to the file jsonSchema.json */
ret = create_schema_file (kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
if (!ret) {
goto fail;
}
/* Load the JSON Schema and construct the local schema_map option. */
reader = bson_json_reader_new_from_file ("jsonSchema.json", &error);
if (!reader) {
goto fail;
}
bson_json_reader_read (reader, &schema, &error);
/* Construct the schema map, mapping the namespace of the collection to the
* schema describing encryption. */
schema_map = BCON_NEW (ENCRYPTED_DB "." ENCRYPTED_COLL, BCON_DOCUMENT (&schema));
auto_encryption_opts = mongoc_auto_encryption_opts_new ();
mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts, keyvault_client);
mongoc_auto_encryption_opts_set_keyvault_namespace (auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts, kms_providers);
mongoc_auto_encryption_opts_set_schema_map (auto_encryption_opts, schema_map);
client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
BSON_ASSERT (client);
/* Enable automatic encryption. It will determine that encryption is
* necessary from the schema map instead of relying on the server to provide
* a schema. */
ret = mongoc_client_enable_auto_encryption (client, auto_encryption_opts, &error);
if (!ret) {
goto fail;
}
coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
/* Clear old data */
mongoc_collection_drop (coll, NULL);
to_insert = BCON_NEW ("encryptedField", "123456789");
ret = mongoc_collection_insert_one (coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
printf ("decrypted document: ");
if (!print_one_document (coll, &error)) {
goto fail;
}
printf ("\n");
unencrypted_client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption-unencrypted");
BSON_ASSERT (unencrypted_client);
unencrypted_coll = mongoc_client_get_collection (unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
printf ("encrypted document: ");
if (!print_one_document (unencrypted_coll, &error)) {
goto fail;
}
printf ("\n");
exit_status = EXIT_SUCCESS;
fail:
if (error.code) {
fprintf (stderr, "error: %s\n", error.message);
}
bson_free (local_masterkey);
bson_destroy (kms_providers);
mongoc_collection_destroy (keyvault_coll);
mongoc_index_model_destroy (index_model);
bson_destroy (index_opts);
bson_destroy (index_keys);
bson_json_reader_destroy (reader);
mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
mongoc_collection_destroy (coll);
mongoc_client_destroy (client);
bson_destroy (to_insert);
mongoc_collection_destroy (unencrypted_coll);
mongoc_client_destroy (unencrypted_client);
mongoc_client_destroy (keyvault_client);
bson_destroy (&schema);
bson_destroy (schema_map);
mongoc_cleanup ();
return exit_status;
}

El servidor MongoDB 4.2 admite la validación de esquemas para forzar el cifrado de campos específicos de una colección. Esta validación evitará que una aplicación inserte valores sin cifrar en los campos marcados con la palabra clave de esquema JSON "encrypt".

El siguiente ejemplo muestra cómo configurar el cifrado automático utilizando mongoc_client_encryption_t para crear una nueva clave de datos de cifrado y crear una colección con el esquema JSON necesario:

esquema-de-servidor-de-cifrado-del-lado-del-cliente.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#include "client-side-encryption-helpers.h"
/* Helper method to create and return a JSON schema to use for encryption.
The caller will use the returned schema for server-side encryption validation.
*/
static bson_t *
create_schema (bson_t *kms_providers,
const char *keyvault_db,
const char *keyvault_coll,
mongoc_client_t *keyvault_client,
bson_error_t *error)
{
mongoc_client_encryption_t *client_encryption = NULL;
mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
bson_value_t datakey_id = {0};
char *keyaltnames[] = {"mongoc_encryption_example_2"};
bson_t *schema = NULL;
client_encryption_opts = mongoc_client_encryption_opts_new ();
mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts, kms_providers);
mongoc_client_encryption_opts_set_keyvault_namespace (client_encryption_opts, keyvault_db, keyvault_coll);
mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts, keyvault_client);
client_encryption = mongoc_client_encryption_new (client_encryption_opts, error);
if (!client_encryption) {
goto fail;
}
/* Create a new data key and json schema for the encryptedField.
* https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
*/
datakey_opts = mongoc_client_encryption_datakey_opts_new ();
mongoc_client_encryption_datakey_opts_set_keyaltnames (datakey_opts, keyaltnames, 1);
if (!mongoc_client_encryption_create_datakey (client_encryption, "local", datakey_opts, &datakey_id, error)) {
goto fail;
}
/* Create a schema describing that "encryptedField" is a string encrypted
* with the newly created data key using deterministic encryption. */
schema = BCON_NEW (
"properties",
"{",
"encryptedField",
"{",
"encrypt",
"{",
"keyId",
"[",
BCON_BIN (datakey_id.value.v_binary.subtype, datakey_id.value.v_binary.data, datakey_id.value.v_binary.data_len),
"]",
"bsonType",
"string",
"algorithm",
MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
"}",
"}",
"}",
"bsonType",
"object");
fail:
mongoc_client_encryption_destroy (client_encryption);
mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
mongoc_client_encryption_opts_destroy (client_encryption_opts);
bson_value_destroy (&datakey_id);
return schema;
}
/* This example demonstrates how to use automatic encryption with a server-side
* schema using the enterprise version of MongoDB */
int
main (void)
{
/* The collection used to store the encryption data keys. */
#define KEYVAULT_DB "encryption"
#define KEYVAULT_COLL "__libmongocTestKeyVault"
/* The collection used to store the encrypted documents in this example. */
#define ENCRYPTED_DB "test"
#define ENCRYPTED_COLL "coll"
int exit_status = EXIT_FAILURE;
bool ret;
uint8_t *local_masterkey = NULL;
uint32_t local_masterkey_len;
bson_t *kms_providers = NULL;
bson_error_t error = {0};
bson_t *index_keys = NULL;
bson_t *index_opts = NULL;
mongoc_index_model_t *index_model = NULL;
bson_json_reader_t *reader = NULL;
bson_t *schema = NULL;
/* The MongoClient used to access the key vault (keyvault_namespace). */
mongoc_client_t *keyvault_client = NULL;
mongoc_collection_t *keyvault_coll = NULL;
mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
mongoc_client_t *client = NULL;
mongoc_collection_t *coll = NULL;
bson_t *to_insert = NULL;
mongoc_client_t *unencrypted_client = NULL;
mongoc_collection_t *unencrypted_coll = NULL;
bson_t *create_cmd = NULL;
bson_t *create_cmd_opts = NULL;
mongoc_write_concern_t *wc = NULL;
mongoc_init ();
/* Configure the master key. This must be the same master key that was used
* to create
* the encryption key. */
local_masterkey = hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
if (!local_masterkey || local_masterkey_len != 96) {
fprintf (stderr,
"Specify LOCAL_MASTERKEY environment variable as a "
"secure random 96 byte hex value.\n");
goto fail;
}
kms_providers = BCON_NEW ("local", "{", "key", BCON_BIN (0, local_masterkey, local_masterkey_len), "}");
/* Set up the key vault for this example. */
keyvault_client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption-keyvault");
BSON_ASSERT (keyvault_client);
keyvault_coll = mongoc_client_get_collection (keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_collection_drop (keyvault_coll, NULL);
/* Create a unique index to ensure that two data keys cannot share the same
* keyAltName. This is recommended practice for the key vault. */
index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
index_opts = BCON_NEW ("unique",
BCON_BOOL (true),
"partialFilterExpression",
"{",
"keyAltNames",
"{",
"$exists",
BCON_BOOL (true),
"}",
"}");
index_model = mongoc_index_model_new (index_keys, index_opts);
ret = mongoc_collection_create_indexes_with_opts (
keyvault_coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
auto_encryption_opts = mongoc_auto_encryption_opts_new ();
mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts, keyvault_client);
mongoc_auto_encryption_opts_set_keyvault_namespace (auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts, kms_providers);
schema = create_schema (kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
if (!schema) {
goto fail;
}
client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
BSON_ASSERT (client);
ret = mongoc_client_enable_auto_encryption (client, auto_encryption_opts, &error);
if (!ret) {
goto fail;
}
coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
/* Clear old data */
mongoc_collection_drop (coll, NULL);
/* Create the collection with the encryption JSON Schema. */
create_cmd = BCON_NEW ("create", ENCRYPTED_COLL, "validator", "{", "$jsonSchema", BCON_DOCUMENT (schema), "}");
wc = mongoc_write_concern_new ();
mongoc_write_concern_set_wmajority (wc, 0);
create_cmd_opts = bson_new ();
mongoc_write_concern_append (wc, create_cmd_opts);
ret = mongoc_client_command_with_opts (
client, ENCRYPTED_DB, create_cmd, NULL /* read prefs */, create_cmd_opts, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
to_insert = BCON_NEW ("encryptedField", "123456789");
ret = mongoc_collection_insert_one (coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
printf ("decrypted document: ");
if (!print_one_document (coll, &error)) {
goto fail;
}
printf ("\n");
unencrypted_client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption-unencrypted");
BSON_ASSERT (unencrypted_client);
unencrypted_coll = mongoc_client_get_collection (unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
printf ("encrypted document: ");
if (!print_one_document (unencrypted_coll, &error)) {
goto fail;
}
printf ("\n");
/* Expect a server-side error if inserting with the unencrypted collection.
*/
ret = mongoc_collection_insert_one (unencrypted_coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
printf ("insert with unencrypted collection failed: %s\n", error.message);
memset (&error, 0, sizeof (error));
}
exit_status = EXIT_SUCCESS;
fail:
if (error.code) {
fprintf (stderr, "error: %s\n", error.message);
}
bson_free (local_masterkey);
bson_destroy (kms_providers);
mongoc_collection_destroy (keyvault_coll);
mongoc_index_model_destroy (index_model);
bson_destroy (index_opts);
bson_destroy (index_keys);
bson_json_reader_destroy (reader);
mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
mongoc_collection_destroy (coll);
mongoc_client_destroy (client);
bson_destroy (to_insert);
mongoc_collection_destroy (unencrypted_coll);
mongoc_client_destroy (unencrypted_client);
mongoc_client_destroy (keyvault_client);
bson_destroy (schema);
bson_destroy (create_cmd);
bson_destroy (create_cmd_opts);
mongoc_write_concern_destroy (wc);
mongoc_cleanup ();
return exit_status;
}

El cifrado explícito es una característica de la comunidad de MongoDB y no utiliza análisis de consultas (mongocryptd crypt_sharedo). El cifrado explícito lo proporciona la clase mongoc_client_encryption_t, por ejemplo:

cifrado explícito del lado del cliente.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#include "client-side-encryption-helpers.h"
/* This example demonstrates how to use explicit encryption and decryption using
* the community version of MongoDB */
int
main (void)
{
/* The collection used to store the encryption data keys. */
#define KEYVAULT_DB "encryption"
#define KEYVAULT_COLL "__libmongocTestKeyVault"
/* The collection used to store the encrypted documents in this example. */
#define ENCRYPTED_DB "test"
#define ENCRYPTED_COLL "coll"
int exit_status = EXIT_FAILURE;
bool ret;
uint8_t *local_masterkey = NULL;
uint32_t local_masterkey_len;
bson_t *kms_providers = NULL;
bson_error_t error = {0};
bson_t *index_keys = NULL;
bson_t *index_opts = NULL;
mongoc_index_model_t *index_model = NULL;
bson_t *schema = NULL;
mongoc_client_t *client = NULL;
mongoc_collection_t *coll = NULL;
mongoc_collection_t *keyvault_coll = NULL;
bson_t *to_insert = NULL;
bson_t *create_cmd = NULL;
bson_t *create_cmd_opts = NULL;
mongoc_write_concern_t *wc = NULL;
mongoc_client_encryption_t *client_encryption = NULL;
mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
char *keyaltnames[] = {"mongoc_encryption_example_3"};
bson_value_t datakey_id = {0};
bson_value_t encrypted_field = {0};
bson_value_t to_encrypt = {0};
mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
bson_value_t decrypted = {0};
mongoc_init ();
/* Configure the master key. This must be the same master key that was used
* to create the encryption key. */
local_masterkey = hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
if (!local_masterkey || local_masterkey_len != 96) {
fprintf (stderr,
"Specify LOCAL_MASTERKEY environment variable as a "
"secure random 96 byte hex value.\n");
goto fail;
}
kms_providers = BCON_NEW ("local", "{", "key", BCON_BIN (0, local_masterkey, local_masterkey_len), "}");
/* The mongoc_client_t used to read/write application data. */
client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
/* Clear old data */
mongoc_collection_drop (coll, NULL);
/* Set up the key vault for this example. */
keyvault_coll = mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_collection_drop (keyvault_coll, NULL);
/* Create a unique index to ensure that two data keys cannot share the same
* keyAltName. This is recommended practice for the key vault. */
index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
index_opts = BCON_NEW ("unique",
BCON_BOOL (true),
"partialFilterExpression",
"{",
"keyAltNames",
"{",
"$exists",
BCON_BOOL (true),
"}",
"}");
index_model = mongoc_index_model_new (index_keys, index_opts);
ret = mongoc_collection_create_indexes_with_opts (
keyvault_coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
client_encryption_opts = mongoc_client_encryption_opts_new ();
mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts, kms_providers);
mongoc_client_encryption_opts_set_keyvault_namespace (client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
/* Set a mongoc_client_t to use for reading/writing to the key vault. This
* can be the same mongoc_client_t used by the main application. */
mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts, client);
client_encryption = mongoc_client_encryption_new (client_encryption_opts, &error);
if (!client_encryption) {
goto fail;
}
/* Create a new data key for the encryptedField.
* https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
*/
datakey_opts = mongoc_client_encryption_datakey_opts_new ();
mongoc_client_encryption_datakey_opts_set_keyaltnames (datakey_opts, keyaltnames, 1);
if (!mongoc_client_encryption_create_datakey (client_encryption, "local", datakey_opts, &datakey_id, &error)) {
goto fail;
}
/* Explicitly encrypt a field */
encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
mongoc_client_encryption_encrypt_opts_set_algorithm (encrypt_opts,
MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
mongoc_client_encryption_encrypt_opts_set_keyid (encrypt_opts, &datakey_id);
to_encrypt.value_type = BSON_TYPE_UTF8;
to_encrypt.value.v_utf8.str = "123456789";
const size_t len = strlen (to_encrypt.value.v_utf8.str);
BSON_ASSERT (bson_in_range_unsigned (uint32_t, len));
to_encrypt.value.v_utf8.len = (uint32_t) len;
ret = mongoc_client_encryption_encrypt (client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
if (!ret) {
goto fail;
}
to_insert = bson_new ();
BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
ret = mongoc_collection_insert_one (coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
printf ("encrypted document: ");
if (!print_one_document (coll, &error)) {
goto fail;
}
printf ("\n");
/* Explicitly decrypt a field */
ret = mongoc_client_encryption_decrypt (client_encryption, &encrypted_field, &decrypted, &error);
if (!ret) {
goto fail;
}
printf ("decrypted value: %s\n", decrypted.value.v_utf8.str);
exit_status = EXIT_SUCCESS;
fail:
if (error.code) {
fprintf (stderr, "error: %s\n", error.message);
}
bson_free (local_masterkey);
bson_destroy (kms_providers);
mongoc_collection_destroy (keyvault_coll);
mongoc_index_model_destroy (index_model);
bson_destroy (index_opts);
bson_destroy (index_keys);
mongoc_collection_destroy (coll);
mongoc_client_destroy (client);
bson_destroy (to_insert);
bson_destroy (schema);
bson_destroy (create_cmd);
bson_destroy (create_cmd_opts);
mongoc_write_concern_destroy (wc);
mongoc_client_encryption_destroy (client_encryption);
mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
mongoc_client_encryption_opts_destroy (client_encryption_opts);
bson_value_destroy (&encrypted_field);
mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
bson_value_destroy (&decrypted);
bson_value_destroy (&datakey_id);
mongoc_cleanup ();
return exit_status;
}

Aunque el cifrado automático requiere MongoDB 4.2 Enterprise o un clúster MongoDB 4.2 Atlas, el descifrado automático es compatible con todos los usuarios. Para configurar el descifrado automático sin el cifrado automático definido bypass_auto_encryption=True en en mongoc_auto_encryption_opts_t:

cifrado del lado del cliente y descifrado automático.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#include "client-side-encryption-helpers.h"
/* This example demonstrates how to set up automatic decryption without
* automatic encryption using the community version of MongoDB */
int
main (void)
{
/* The collection used to store the encryption data keys. */
#define KEYVAULT_DB "encryption"
#define KEYVAULT_COLL "__libmongocTestKeyVault"
/* The collection used to store the encrypted documents in this example. */
#define ENCRYPTED_DB "test"
#define ENCRYPTED_COLL "coll"
int exit_status = EXIT_FAILURE;
bool ret;
uint8_t *local_masterkey = NULL;
uint32_t local_masterkey_len;
bson_t *kms_providers = NULL;
bson_error_t error = {0};
bson_t *index_keys = NULL;
bson_t *index_opts = NULL;
mongoc_index_model_t *index_model = NULL;
bson_t *schema = NULL;
mongoc_client_t *client = NULL;
mongoc_collection_t *coll = NULL;
mongoc_collection_t *keyvault_coll = NULL;
bson_t *to_insert = NULL;
bson_t *create_cmd = NULL;
bson_t *create_cmd_opts = NULL;
mongoc_write_concern_t *wc = NULL;
mongoc_client_encryption_t *client_encryption = NULL;
mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
char *keyaltnames[] = {"mongoc_encryption_example_4"};
bson_value_t datakey_id = {0};
bson_value_t encrypted_field = {0};
bson_value_t to_encrypt = {0};
mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
bson_value_t decrypted = {0};
mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
mongoc_client_t *unencrypted_client = NULL;
mongoc_collection_t *unencrypted_coll = NULL;
mongoc_init ();
/* Configure the master key. This must be the same master key that was used
* to create the encryption key. */
local_masterkey = hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
if (!local_masterkey || local_masterkey_len != 96) {
fprintf (stderr,
"Specify LOCAL_MASTERKEY environment variable as a "
"secure random 96 byte hex value.\n");
goto fail;
}
kms_providers = BCON_NEW ("local", "{", "key", BCON_BIN (0, local_masterkey, local_masterkey_len), "}");
client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
auto_encryption_opts = mongoc_auto_encryption_opts_new ();
mongoc_auto_encryption_opts_set_keyvault_namespace (auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts, kms_providers);
/* Setting bypass_auto_encryption to true disables automatic encryption but
* keeps the automatic decryption behavior. bypass_auto_encryption will also
* disable spawning mongocryptd */
mongoc_auto_encryption_opts_set_bypass_auto_encryption (auto_encryption_opts, true);
/* Once bypass_auto_encryption is set, community users can enable auto
* encryption on the client. This will, in fact, only perform automatic
* decryption. */
ret = mongoc_client_enable_auto_encryption (client, auto_encryption_opts, &error);
if (!ret) {
goto fail;
}
/* Now that automatic decryption is on, we can test it by inserting a
* document with an explicitly encrypted value into the collection. When we
* look up the document later, it should be automatically decrypted for us.
*/
coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
/* Clear old data */
mongoc_collection_drop (coll, NULL);
/* Set up the key vault for this example. */
keyvault_coll = mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
mongoc_collection_drop (keyvault_coll, NULL);
/* Create a unique index to ensure that two data keys cannot share the same
* keyAltName. This is recommended practice for the key vault. */
index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
index_opts = BCON_NEW ("unique",
BCON_BOOL (true),
"partialFilterExpression",
"{",
"keyAltNames",
"{",
"$exists",
BCON_BOOL (true),
"}",
"}");
index_model = mongoc_index_model_new (index_keys, index_opts);
ret = mongoc_collection_create_indexes_with_opts (
keyvault_coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
client_encryption_opts = mongoc_client_encryption_opts_new ();
mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts, kms_providers);
mongoc_client_encryption_opts_set_keyvault_namespace (client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
/* The key vault client is used for reading to/from the key vault. This can
* be the same mongoc_client_t used by the application. */
mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts, client);
client_encryption = mongoc_client_encryption_new (client_encryption_opts, &error);
if (!client_encryption) {
goto fail;
}
/* Create a new data key for the encryptedField.
* https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
*/
datakey_opts = mongoc_client_encryption_datakey_opts_new ();
mongoc_client_encryption_datakey_opts_set_keyaltnames (datakey_opts, keyaltnames, 1);
ret = mongoc_client_encryption_create_datakey (client_encryption, "local", datakey_opts, &datakey_id, &error);
if (!ret) {
goto fail;
}
/* Explicitly encrypt a field. */
encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
mongoc_client_encryption_encrypt_opts_set_algorithm (encrypt_opts,
MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
mongoc_client_encryption_encrypt_opts_set_keyaltname (encrypt_opts, "mongoc_encryption_example_4");
to_encrypt.value_type = BSON_TYPE_UTF8;
to_encrypt.value.v_utf8.str = "123456789";
const size_t len = strlen (to_encrypt.value.v_utf8.str);
BSON_ASSERT (bson_in_range_unsigned (uint32_t, len));
to_encrypt.value.v_utf8.len = (uint32_t) len;
ret = mongoc_client_encryption_encrypt (client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
if (!ret) {
goto fail;
}
to_insert = bson_new ();
BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
ret = mongoc_collection_insert_one (coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
if (!ret) {
goto fail;
}
/* When we retrieve the document, any encrypted fields will get automatically
* decrypted by the driver. */
printf ("decrypted document: ");
if (!print_one_document (coll, &error)) {
goto fail;
}
printf ("\n");
unencrypted_client = mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
unencrypted_coll = mongoc_client_get_collection (unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
printf ("encrypted document: ");
if (!print_one_document (unencrypted_coll, &error)) {
goto fail;
}
printf ("\n");
exit_status = EXIT_SUCCESS;
fail:
if (error.code) {
fprintf (stderr, "error: %s\n", error.message);
}
bson_free (local_masterkey);
bson_destroy (kms_providers);
mongoc_collection_destroy (keyvault_coll);
mongoc_index_model_destroy (index_model);
bson_destroy (index_opts);
bson_destroy (index_keys);
mongoc_collection_destroy (coll);
mongoc_client_destroy (client);
bson_destroy (to_insert);
bson_destroy (schema);
bson_destroy (create_cmd);
bson_destroy (create_cmd_opts);
mongoc_write_concern_destroy (wc);
mongoc_client_encryption_destroy (client_encryption);
mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
mongoc_client_encryption_opts_destroy (client_encryption_opts);
bson_value_destroy (&encrypted_field);
mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
bson_value_destroy (&decrypted);
bson_value_destroy (&datakey_id);
mongoc_collection_destroy (unencrypted_coll);
mongoc_client_destroy (unencrypted_client);
mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
mongoc_cleanup ();
return exit_status;
}

Volver

Encriptación en uso

En esta página