Docs Menu
Docs Home
/ /

使用中の暗号化

使用中の暗号化は、 MongoDBコレクション内の機密データを暗号化する 2 つの機能を提供します。

  • クライアント側のフィールドレベル暗号化 -クライアント側の特定のデータフィールドを暗号化

  • Queryable Encryption - 暗号化されたフィールドをクエリ能力を維持しながらデータを暗号化する

どちらの機能も、サーバー管理者を含む権限のないユーザーが暗号化されたデータを読み取れないことを保証します。

libmongocrypt使用中の暗号化を使用するには、 を依存関係としてインストールする必要があります。完全なインストールガイドについては、 MongoDB Serverマニュアルのlibmongocrypt インストール手順を参照してください。

libmongocrypt をインストールした後、次の例に示すように、 Cドライバーを -DENABLE_CLIENT_SIDE_ENCRYPTION=ON で構成して、使用中の暗号化を有効にします。

$ 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マニュアルの 「自動暗号化共有ライブラリ」ガイドを参照してください。

自動暗号化が設定された mongoc_client_t または mongoc_client_Pool_tcrypt_shared は、自動的に ライブラリのロードを試行します。crypt_shared ライブラリのロードに失敗した場合、mongoc_client_t または mongoc_client_Pool_t mongocryptdは、アプリケーションの から プロセスを生成しようとします。PATHcrypt_shared mongocryptdの使用を構成するには、 mongoc_auto_encryption_ops_set_Extra を参照してください。

明示的な暗号化とキー管理には、 mongoc_client_encryption_t を使用します。自動暗号化を有効にするには、 mongoc_client_enable_auto_encryption mongoc_client_Pool_enable_auto_encryption を使用します。

Queryable Encryption (QE)とクライアント側フィールドレベル暗号化(CSFLE)機能は、一部の例外を除いて、同じAPIの多くを共有します。

CSFLE を使用すると、管理者と開発者は、 MongoDB の他の暗号化機能に加えて特定のデータ フィールドを暗号化できます。

CSFLE を使用すると、サーバー側の設定やディレクティブを使用せずに、クライアント側でフィールドを暗号化できます。 CSFLE は、サーバー管理者を含む権限のないユーザーが暗号化されたデータを読み取れることをアプリケーションが保証する必要があるワークロードをサポートします。

自動暗号化。コマンドの機密フィールドが自動的に暗号化される場合、クエリ分析にはエンタープライズのみの依存関係が必要です。詳細については、「 クエリ分析 」を参照してください。

Tip

The Client-Side Field Level Encryption guide in the MongoDB Server manual

mongoc_client_tオブジェクトで mongoc_client_enable_auto_encryption を呼び出して、自動暗号化を有効にします。次の例は、 mongoc_client_encryption_t を使用して新しい暗号化データキーを作成し、自動暗号化を設定する方法を示しています。

注意

自動暗号化にはMongoDB Enterprise Advanced4.2 以降、またはMongoDB 以降の4.2 Atlas クラスターが必要です。 MongoDB Serverの Community バージョンは、自動復号化と明示的な暗号化をサポートしています。

スキーママップを使用して、自動暗号化ルールを指定できます。スキーママップを作成するには、 mongoc_auto_encryption_opts_set_schema_map 関数を呼び出します。自動暗号化ルールは、 JSON schema構文の厳密なサブセットを使用します。

スキーマ マップを提供すると、サーバーから取得した JSON schema に依存する場合よりもセキュリティが高くなります。 これにより、誤った JSON schema を広告する悪意のサーバーから保護されます。これにより、クライアントが暗号化されなければならない暗号化されていないデータを送信する可能性があります。

スキーママップで提供されているJSON schema は、自動暗号化 の構成にのみ適用されます。 JSON スキーマの他の検証ルールはドライバーによって強制されないため、エラーが発生します。

次の例では、mongoc_auto_encryption_opts_set_schema_map() 関数を使用して、自動暗号化ルールを指定するスキーママップを作成しています。

クライアント側暗号化-schema-map.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#define FAIL(...) \
fprintf(stderr, "Error [%s:%d]:\n", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
abort();
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes.
#define init_bson(bson, json) \
if (!bson_init_from_json(&bson, json, -1, &error)) { \
FAIL("Failed to create BSON: %s", error.message); \
}
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 検証ルールで構成されたコレクションの両方を作成する必要があります。

クライアント側暗号化サーバーサーバースキーマ.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#define FAIL(...) \
fprintf(stderr, "Error [%s:%d]:\n", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
abort();
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes.
#define init_bson(bson, json) \
if (!bson_init_from_json(&bson, json, -1, &error)) { \
FAIL("Failed to create BSON: %s", error.message); \
}
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 mongocryptdcrypt_sharedの機能であり、クエリ分析は使用されません( または )。明示的な暗号化では、 mongoc_client_encryption_tクラスを使用します。次の例は、明示的な暗号化と復号化を使用する方法を示しています。

クライアント側暗号化明示的.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#define FAIL(...) \
fprintf(stderr, "Error [%s:%d]:\n", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
abort();
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes.
#define init_bson(bson, json) \
if (!bson_init_from_json(&bson, json, -1, &error)) { \
FAIL("Failed to create BSON: %s", error.message); \
}
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クラスターが必要ですが、すべてのMongoDB Server製品は自動復号化をサポートしています。自動復号化を使用して明示的な暗号化を構成するには、次の例に示すように、bypass_auto_encryption=True mongoc_auto_encryption_ops_t で を設定します。

クライアント側暗号化自動復号化.c
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#define FAIL(...) \
fprintf(stderr, "Error [%s:%d]:\n", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
abort();
// `init_bson` creates BSON from JSON. Aborts on error. Use the `BSON_STR()` macro to avoid quotes.
#define init_bson(bson, json) \
if (!bson_init_from_json(&bson, json, -1, &error)) { \
FAIL("Failed to create BSON: %s", error.message); \
}
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 は、使用可能な次の暗号化機能であり、MongoDB Server バージョン 6.0 のプレビュー機能として導入され、その後 MongoDB 7.0 の一般提供(GA)機能として導入されます。 Queryable Encryption は、暗号化されたフィールドで等価性を検索することをサポートしており、各値を一意に暗号化します。

注意

QE にはMongoDB Server 7.0 以降が必要

MongoDB Server配置を6.0 から7.0 にアップグレードする方法の詳細については、 MongoDB Serverマニュアルの 「 6.07から. へのアップグレード」 を参照してください。0

機能の詳細については、 MongoDB Serverマニュアルの「 Queryable Encryption 」ガイドを参照してください。

MongoDB Server6.0 では、 Queryable Encryption がパブリック テクニカル プレビューとして導入されています。 MongoDB Server7.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以降

重要

バージョン一致エラー

上記の表にリストされているパッケージと互換性のないバージョンを使用すると、サーバーエラーが発生します。

戻る

認証

項目一覧