AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

使用中の暗号化

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

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

使用中の暗号化を使用するには、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は、アプリケーションの から プロセスを生成しようとします。PATH とcrypt_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

MongoDB Serverマニュアルの 「クライアント側フィールドレベル暗号化」ガイド。

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

注意

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

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

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

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

次の例では、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 キーワードでマークされたフィールドに暗号化されていない値を挿入するのを防止します。

サーバー側の実装を行うには、次の例に示すように、暗号化データキーと適切なスキーマ検証ルールで構成されたコレクションの両方を作成する必要があります。

クライアント側暗号化サーバーサーバースキーマ.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製品は自動復号化をサポートしています。自動復号化を使用して明示的な暗号化を構成するには、次の例に示すように、 mongoc_auto_encryption_opts_t で bypass_auto_encryption=True を設定します。

クライアント側暗号化自動復号化.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 (QE) は、使用中の暗号化機能で、暗号化されたフィールド値に対して、等価、範囲、プレフィックス、サフィックス、および部分文字列のクエリを実行できます。範囲クエリのサポートにはMongoDB Server 8.0 以降が必要です。プレフィックス、サフィックス、および部分文字列クエリのサポートにはMongoDB Server 9.0 以降が必要です。

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