문서 메뉴
문서 홈
/ / /
C 드라이버
/ / /

Client-Side Field Level Encryption

이 페이지의 내용

  • 자동 클라이언트 사이드 필드 레벨 암호화
  • 로컬 자동 암호화 규칙 제공
  • 서버측 필드 레벨 암호화 시행
  • 명시적 암호화
  • 자동 암호 해독을 통한 명시적 암호화

MongoDB 4 의 새로운 기능 2, 클라이언트 측 필드 레벨 암호화(CSFLE라고도 함)를 사용하면 관리자와 개발자가 다른 MongoDB 암호화 기능 외에도 특정 데이터 필드를 암호화할 수 있습니다.

개발자는 CSFLE를 사용하여 서버 사이드 구성이나 지시문 없이 클라이언트 사이드에서 필드를 암호화할 수 있습니다. CSFLE는 서버 관리자를 포함한 권한이 없는 당사자가 암호화된 데이터를 읽을 수 없도록 애플리케이션이 보장해야 하는 워크로드를 지원합니다.

명령의 민감한 필드가 자동으로 암호화되는 자동 암호화에는 쿼리 분석에 대한 엔터프라이즈 전용 종속성이 필요합니다. 자세한 내용은 사용 중 암호화 를 참조하세요.

다음도 참조하세요.

The MongoDB Manual for Client-Side Field Level Encryption

mongoc_client_enable_auto_encryption 을 호출하여 자동 암호화를 활성화합니다.mongoc_client_t 에서 . 다음 예시는 mongoc_client_encryption_t 를 사용하여 자동 암호화를 설정하는 방법을 보여줍니다. 새 암호화 데이터 키를 생성합니다.

참고

자동 암호화에는 MongoDB 4.2 엔터프라이즈 또는 MongoDB 4.2 이 필요합니다. Atlas cluster. 서버의 커뮤니티 버전은 자동 암호 해독과 명시적 암호화를 지원합니다.

다음 예는 mongoc_auto_encryption_opts_set_schema_map 으로 설정된 스키마 맵을 사용하여 자동 암호화 규칙을 지정하는 방법을 보여줍니다. . 자동 암호화 규칙은 JSON Schema 구문의 엄격한 하위 집합을 사용하여 표현됩니다.

스키마 맵을 제공하면 서버에서 얻은 JSON Schema에 의존하는 것보다 더 강력한 보안이 제공됩니다. 악의적인 서버가 잘못된 JSON Schema를 광고하여 클라이언트를 속여 암호화되어야 하는 암호화되지 않은 데이터를 보내도록 할 수 있습니다.

스키마 맵에 제공된 JSON Schema는 자동 암호화 구성에만 적용됩니다. JSON schema의 다른 유효성 검사 규칙은 드라이버에서 적용되지 않으므로 오류가 발생합니다.

client-side-encryption-schema-map.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;
}

MongoDB 4.2 서버는 스키마 유효성 검사를 사용하여 컬렉션의 특정 필드에 암호화를 적용하는 것을 지원합니다. 이 스키마 유효성 검사는 애플리케이션이 "encrypt" JSON schema 키워드로 표시된 필드에 암호화되지 않은 값을 삽입하는 것을 방지합니다.

다음 예는 mongoc_client_encryption_t 를 사용하여 자동 암호화를 설정하는 방법을 보여줍니다. 새 암호화 데이터 키를 생성하고 필요한 JSON Schema를 사용하여 컬렉션을 생성합니다.

client-side-encryption-server-schema.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;
}

명시적 암호화는 MongoDB 커뮤니티 기능이며 쿼리 분석 (mongocryptd 또는 crypt_shared)을 사용하지 않습니다. 명시적 암호화는 mongoc_client_encryption_t 클래스입니다.

client-side-encryption-explicit.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;
}

자동 암호화에는 MongoDB 4 이(가) 필요합니다.2 엔터프라이즈 또는 MongoDB 4 2. Atlas cluster에서는 모든 사용자에 대해 자동 암호 해독이 지원됩니다. 자동 암호화 없이 자동 암호 해독을 구성하려면 bypass_auto_encryption=True mongoc_auto_encryption_opts_t 에서 를 설정합니다.

client-side-encryption-auto-decryption.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;
}

돌아가기

사용 중 암호화

다음

Queryable Encryption