クライアントサイドのフィールド レベル暗号化
MongoDB 4.2の新機能 、 クライアント側フィールドレベル暗号化(CSFLEとも呼ばれる)を使用すると、管理者と開発者は MongoDB の他の暗号化機能に加えて、特定のデータフィールドを暗号化できます。
CSFLE を使用すると、開発者はサーバー側の構成やディレクティブを使用せずに、クライアント側のフィールドを暗号化できます。 CSFLE は、サーバー管理者を含む権限のないユーザーが暗号化されたデータを読み取れることをアプリケーションが保証する必要があるワークロードをサポートします。
コマンド内の機密フィールドが自動的に暗号化される自動暗号化では、クエリ分析にエンタープライズのみの依存関係が必要です。 詳細については、「 使用中の暗号化」を参照してください。
クライアント側のフィールドレベル自動暗号化
mongoc_client_enable_auto_encryption を呼び出すと自動暗号化が有効になります mongoc_client_t の場合 。次の例は、 mongoc_client_encryption_t を使用して自動暗号化を設定する方法を示しています。 新しい暗号化データキーを作成します。
注意
自動暗号化には MongoDB 4.2 Enterprise または MongoDB 4.2 800} が必要です Atlas クラスター。 サーバーのコミュニティ バージョンは、自動復号化と明示的な暗号化をサポートしています。
ローカル自動暗号化ルールの提供
次の例は、 mongoc_auto_encryption_opts_set_schema_map で設定されたスキーマ マップセットを使用して、自動暗号化ルールを指定する方法を示しています。 。自動暗号化ルールは、 JSON schema 構文の厳密なサブセットを使用して表現されます。
スキーマ マップを提供すると、サーバーから取得した JSON schema に依存する場合よりもセキュリティが高くなります。 これにより、誤った JSON schema を広告する悪意のサーバーから保護されます。これにより、クライアントが暗号化されなければならない暗号化されていないデータを送信する可能性があります。
スキーマ マップで提供されている JSON schema は、自動暗号化の構成にのみ適用されます。 JSON schema の他の検証ルールはドライバーによって強制されないため、エラーが発生します。
/* 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. */ /* The collection used to store the encrypted documents in this example. */ 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 を含むコレクションを作成します。
/* 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. */ /* The collection used to store the encrypted documents in this example. */ 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 Community の機能であり、クエリ分析は使用されません( mongocryptd
またはcrypt_shared
)。 明示的な暗号化は mongoc_client_encryption_t メソッド によって提供されます クラス、たとえば次のとおりです。
/* 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. */ /* The collection used to store the encrypted documents in this example. */ 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 Enterprise または MongoDB 4.2 800} が必要です Atlas クラスターでは、すべてのユーザーに対して自動復号化がサポートされています。 自動暗号化を使用せずに自動復号化を構成するには、bypass_auto_encryption=True
mongoc_auto_encryption_ops_t で を設定します。
/* 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. */ /* The collection used to store the encrypted documents in this example. */ 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; }