사용 중 암호화 MongoDB 컬렉션의 민감한 데이터를 암호화하는 두 가지 기능을 제공합니다.
클라이언트 측 필드 레벨 암호화 - 클라이언트 사이드 특정 데이터 필드를 암호화합니다.
Queryable Encryption - 암호화됨 필드를 쿼리 기능 을 유지하면서 데이터를 암호화합니다.
두 기능 모두 서버 관리자를 포함한 권한이 없는 당사자가 암호화됨 데이터를 읽을 수 없도록 합니다.
설치
libmongocrypt 사용 중 암호화 사용하려면 을 종속성으로 설치해야 합니다. 전체 설치 가이드 는 MongoDB Server 매뉴얼의 libmongocrypt 설치 지침을 참조하세요.
libmongocrypt을(를) 설치한 후 다음 예시 와 같이 -DENABLE_CLIENT_SIDE_ENCRYPTION=ON (으)로 C 운전자 구성하여 사용 중 암호화 활성화 .
$ cd mongo-c-driver $ mkdir cmake-build && cd cmake-build $ cmake -DENABLE_CLIENT_SIDE_ENCRYPTION=ON .. $ cmake --build . --target install
쿼리 분석
자동 암호화 지원 하려면 다음 종속성 중 하나가 필요합니다.
mongocryptd실행 파일입니다. 설치 지침은 MongoDB Server 매뉴얼의 mongocryptd 가이드 참조하세요.crypt_shared라이브러리. 자세한 내용은 MongoDB Server 매뉴얼의 자동 암호화 공유 라이브러리 가이드 참조하세요.
자동 crypt_shared 암호화 crypt_shared 로 구성된 mongoc_client_t 또는 mongoc_client_pool_t가 자동으로 라이브러리를 로드하려고 시도합니다. 라이브러리 로드에 실패하면 mongoc_client_t 또는 mongoc_client_pool_t가 mongocryptd 애플리케이션의 에서 프로세스 생성하려고 PATH 시도합니다. 및 사용을 구성하려면 crypt_shared mongocryptd mongoc_auto_encryption_opts_set_extra를 참조하세요.
API
명시적 암호화 및 키 관리 위해서는 mongoc_client_encryption_t를 사용하세요. mongoc_client_enable_auto_encryption 및 mongoc_client_pool_enable_auto_encryption을 사용하여 자동 암호화 활성화 .
Queryable Encryption (QE) 및 클라이언트 측 필드 레벨 암호화 (CSFLE) 기능은 다음과 같은 몇 가지 예외를 제외하고는 동일한 API 대부분 주식 .
mongoc_client_encryption_encrypt_opts_set_algorithm 에 설명된 지원 알고리즘은 두 기능에 모두 적용 되지 않습니다.
mongoc_auto_encryption_opts_set_encrypted_fields_map은 Queryable Encryption 에만 적용됩니다.
mongoc_auto_encryption_opts_set_schema_map은 CSFLE에만 적용됩니다.
클라이언트 사이드 필드 레벨 암호화
관리자와 개발자는 CSFLE를 사용하여 다른 MongoDB 암호화 기능 외에도 특정 데이터 필드를 암호화할 수 있습니다.
CSFLE를 사용하면 서버 사이드 구성이나 지시문 없이 클라이언트 사이드에서 필드를 암호화할 수 있습니다. CSFLE는 서버 관리자를 포함한 권한이 없는 당사자가 암호화됨 데이터를 읽을 수 없도록 애플리케이션이 보장해야 하는 워크로드를 지원합니다.
명령의 민감한 필드가 자동으로 암호화되는 자동 암호화 에는 쿼리 분석에 대한 엔터프라이즈 전용 종속성이 필요합니다. 자세한 내용은 쿼리 분석을 참조하세요.
팁
자동 클라이언트 사이드 필드 레벨 암호화
mongoc_client_t 객체 에서 mongoc_client_enable_auto_encryption을 호출하여 자동 암호화 활성화합니다. 다음 예제에서는 mongoc_client_encryption_t를 사용하여 새 암호화 데이터 키를 생성하여 자동 암호화 설정하다 방법을 보여 줍니다.
참고
자동 암호화 에는 MongoDB Enterprise Advanced 이상 4.2 또는 MongoDB 이상의 4.2 Atlas cluster 필요합니다. MongoDB Server 의 커뮤니티 버전은 자동 암호 해독 및 명시적 암호화를 지원합니다.
로컬 자동 암호화 규칙 제공
스키마 맵을 사용하여 자동 암호화 규칙을 지정할 수 있습니다. 스키마 맵을 생성하려면 mongoc_auto_encryption_opts_set_schema_map 함수를 호출합니다. 자동 암호화 규칙은 JSON Schema 구문의 엄격한 하위 집합을 사용합니다.
스키마 맵을 제공하면 서버 에서 얻은 JSON Schema에 의존하는 것보다 더 강력한 보안이 제공됩니다. 악의적인 서버 가 잘못된 JSON schema 를 광고하여 클라이언트 를 속여 암호화되어야 하는 암호화됨 되지 않은 데이터를 보내도록 할 수 있습니다.
스키마 맵에 제공된 JSON Schema는 자동 암호화 구성에만 적용 . JSON schema 의 다른 유효성 검사 규칙은 운전자 에서 적용되지 않으므로 오류가 발생합니다.
다음 예시 mongoc_auto_encryption_opts_set_schema_map() 함수를 사용하여 자동 암호화 규칙을 지정하는 스키마 맵을 만듭니다.
// `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; }
서버측 필드 레벨 암호화 시행
MongoDB Server 스키마 유효성 검사 사용하여 컬렉션 의 특정 필드에 암호화 시행하다 있도록 지원합니다. 이 스키마 유효성 검사 애플리케이션 encrypt JSON Schema 키워드로 표시된 필드에 암호화되지 않은 값을 삽입하는 것을 방지합니다.
서버 측 시행을 구현 하려면 다음 예시 와 같이 암호화 데이터 키와 적절한 JSON Schema 유효성 검사 규칙으로 구성된 컬렉션 모두 생성해야 합니다.
// `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; }
명시적 암호화
명시적 암호화 사용하여 데이터베이스 에서 수행하는 각 작업에 대해 문서 의 필드를 암호화하는 방법을 지정할 수 있습니다. 명시적 암호화 사용할 때는 자체 암호화 데이터 키와 암호화 옵션을 정의해야 합니다.
명시적 암호화 는 MongoDB Community Edition 기능 이며 쿼리 분석(mongocryptd crypt_shared또는)을 사용하지 않습니다. 명시적 암호화 mongoc_client_encryption_t 클래스를 사용합니다. 다음 예시 명시적 암호화 및 암호 해독을 사용하는 방법을 보여 줍니다.
// `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; }
자동 암호 해독을 통한 명시적 암호화
자동 암호화 MongoDB Enterprise Advanced 또는 MongoDB Atlas cluster 필요하지만 모든 MongoDB Server 제품은 자동 암호 해독을 지원 . 자동 복호화를 사용하여 명시적 암호화를 구성하려면 bypass_auto_encryption=True 다음 예시 와 같이 mongoc_auto_encryption_opts_t 에서 을 설정하다 .
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes. int main(void) { bson_error_t error; // The key vault collection stores encrypted data keys: const char *keyvault_db_name = "keyvault"; const char *keyvault_coll_name = "datakeys"; // The encrypted collection stores application data: const char *encrypted_db_name = "db"; const char *encrypted_coll_name = "coll"; // Set `local_key` to a 96 byte base64-encoded string: const char *local_key = "qx/3ydlPRXgUrBvSBWLsllUTaYDcS/pyaVo27qBHkS2AFePjInwhzCmDWHdmCYPmzhO4lRBzeZKFjSafduLL5z5DMvR/" "QFfV4zc7btcVmV3QWbDwqZyn6G+Y18ToLHyK"; const char *uri = "mongodb://localhost/?appname=client-side-encryption"; mongoc_init(); // Configure KMS providers used to encrypt data keys: bson_t kms_providers; { char *as_json = bson_strdup_printf(BSON_STR({"local" : {"key" : "%s"}}), local_key); init_bson(kms_providers, as_json); bson_free(as_json); } // Create client configured to automatically decrypt: mongoc_client_t *client; { client = mongoc_client_new(uri); if (!client) { FAIL("Failed to create client"); } mongoc_auto_encryption_opts_t *ae_opts = mongoc_auto_encryption_opts_new(); // Bypass automatic encryption (requires mongocryptd/crypt_shared) but keep automatic decryption: mongoc_auto_encryption_opts_set_bypass_auto_encryption(ae_opts, true); mongoc_auto_encryption_opts_set_keyvault_namespace(ae_opts, keyvault_db_name, keyvault_coll_name); mongoc_auto_encryption_opts_set_kms_providers(ae_opts, &kms_providers); if (!mongoc_client_enable_auto_encryption(client, ae_opts, &error)) { FAIL("Failed to enable auto encryption: %s", error.message); } mongoc_auto_encryption_opts_destroy(ae_opts); } // Set up key vault collection: { mongoc_collection_t *coll = mongoc_client_get_collection(client, keyvault_db_name, keyvault_coll_name); mongoc_collection_drop(coll, NULL); // Clear pre-existing data. // Create index to ensure keys have unique keyAltNames: bson_t index_keys, index_opts; init_bson(index_keys, BSON_STR({"keyAltNames" : 1})); init_bson(index_opts, BSON_STR({"unique" : true, "partialFilterExpression" : {"keyAltNames" : {"$exists" : true}}})); mongoc_index_model_t *index_model = mongoc_index_model_new(&index_keys, &index_opts); if (!mongoc_collection_create_indexes_with_opts( coll, &index_model, 1, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to create index: %s", error.message); } mongoc_index_model_destroy(index_model); bson_destroy(&index_opts); bson_destroy(&index_keys); mongoc_collection_destroy(coll); } // Create ClientEncryption object: mongoc_client_encryption_t *client_encryption; { mongoc_client_encryption_opts_t *ce_opts = mongoc_client_encryption_opts_new(); mongoc_client_encryption_opts_set_kms_providers(ce_opts, &kms_providers); mongoc_client_encryption_opts_set_keyvault_namespace(ce_opts, keyvault_db_name, keyvault_coll_name); mongoc_client_encryption_opts_set_keyvault_client(ce_opts, client); client_encryption = mongoc_client_encryption_new(ce_opts, &error); if (!client_encryption) { FAIL("Failed to create ClientEncryption: %s", error.message); } mongoc_client_encryption_opts_destroy(ce_opts); } // Create data key (see: // https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules): bson_value_t datakey_id; { mongoc_client_encryption_datakey_opts_t *dk_opts = mongoc_client_encryption_datakey_opts_new(); if (!mongoc_client_encryption_create_datakey(client_encryption, "local", dk_opts, &datakey_id, &error)) { FAIL("Failed to create data key: %s", error.message); } mongoc_client_encryption_datakey_opts_destroy(dk_opts); } // Explicitly encrypt a value: bson_value_t encrypted_value; { mongoc_client_encryption_encrypt_opts_t *e_opts = mongoc_client_encryption_encrypt_opts_new(); mongoc_client_encryption_encrypt_opts_set_algorithm(e_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC); mongoc_client_encryption_encrypt_opts_set_keyid(e_opts, &datakey_id); bson_value_t to_encrypt = {.value_type = BSON_TYPE_INT32, .value = {.v_int32 = 123}}; if (!mongoc_client_encryption_encrypt(client_encryption, &to_encrypt, e_opts, &encrypted_value, &error)) { FAIL("Failed to encrypt field: %s", error.message); } mongoc_client_encryption_encrypt_opts_destroy(e_opts); } // Insert document with encrypted payload: mongoc_collection_t *encrypted_coll = mongoc_client_get_collection(client, encrypted_db_name, encrypted_coll_name); { mongoc_collection_drop(encrypted_coll, NULL); // Clear pre-existing data. bson_t to_insert = BSON_INITIALIZER; BSON_APPEND_VALUE(&to_insert, "encryptedField", &encrypted_value); if (!mongoc_collection_insert_one(encrypted_coll, &to_insert, NULL /* opts */, NULL /* reply */, &error)) { FAIL("Failed to insert: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(&to_insert, NULL); printf("Inserted document with encrypted payload: %s\n", as_str); bson_free(as_str); bson_destroy(&to_insert); } // Retrieve document (automatically decrypts): { bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(encrypted_coll, &filter, NULL, NULL); const bson_t *result; if (!mongoc_cursor_next(cursor, &result)) { FAIL("Failed to find inserted document: %s", error.message); } char *as_str = bson_as_relaxed_extended_json(result, NULL); printf("Retrieved document with automatic decryption: %s\n", as_str); bson_free(as_str); mongoc_cursor_destroy(cursor); bson_destroy(&filter); } mongoc_collection_destroy(encrypted_coll); bson_value_destroy(&encrypted_value); bson_value_destroy(&datakey_id); mongoc_client_encryption_destroy(client_encryption); bson_destroy(&kms_providers); mongoc_client_destroy(client); mongoc_cleanup(); return 0; }
Queryable Encryption
Queryable Encryption은 차세대 사용 중 암호화 기능으로, MongoDB Server 버전 6.0에서 미리보기 기능으로 처음 도입되었으며, MongoDB 7.0에서는 정식 버전(GA) 기능으로 출시되었습니다. Queryable Encryption은 암호화된 필드에 대한 동일성 검색을 지원하고 각 값을 고유하게 암호화합니다.
참고
QE에는 MongoDB Server 7.0 이상이 필요합니다.
MongoDB Server 배포서버 를 6.0 에서 으로 업그레이드하는 방법에 대한 7.0 자세한 6.0 70 내용은 MongoDB Server 매뉴얼에서 을 로 업그레이드를 참조하세요.
이 기능 에 대한 자세한 내용은 MongoDB Server 매뉴얼의 Queryable Encryption 가이드 참조하세요.
MongoDB Server 6.0의 QE
MongoDB Server 6.0 은 Queryable Encryption 공개 기술 미리 보기로 도입했습니다. MongoDB Server 7.0 에는 서로 다른 버전의 운전자 라이브러리와 서버 간의 호환성에 영향을 미치는 Queryable Encryption 프로토콜 에 대한 이전 버전과의 호환성이 손상되는 변경이 포함되어 있습니다.
다음 표는 Queryable Encryption 과 호환되는 버전을 보여줍니다.
libmongocrypt | libmongoc | 호환되는 MongoDB Server 버전 |
|---|---|---|
1.7.x 및 이전 버전 | 1.23.x 및 이전 버전 | 6.0 전용 |
1.8.0 이상 | 1.24.0 이상 | 7.0 이상 |
중요
버전 불일치 오류
앞의 표에 나열된 호환되지 않는 버전의 패키지를 사용하면 서버 오류가 발생합니다.