Docs Menu
Docs Home
/
MongoDBマニュアル
/ / / / /

KMIP による自動 Queryable Encryption の使用

項目一覧

  • Overview
  • 始める前に
  • KMS を設定する
  • KMIP 準拠のキー プロバイダーを設定する
  • 証明書を指定する
  • アプリケーションを作成する
  • キーヴォールト コレクションでの一意のインデックスの作成
  • データ暗号化キーの作成
  • MongoClient の設定
  • 暗号化されたフィールドを含むドキュメントの挿入
  • 暗号化されたドキュメントの取得
  • 詳細

このガイドでは、KMIP(Key Management Interoperability Protocol)準拠のキープロバイダーを使用して、Queryable Encryption( QE )対応のアプリケーションを構築する方法について説明します。

このガイドの手順を完了すると、次のものが作成されます。

  • KMIP準拠のキー プロバイダーでホストされている カスタマー マスター キー です。

  • カスタマー マスター キーを使用して暗号化されたドキュメントを挿入する動作するクライアント アプリケーション。

このガイドのコードを完了して実行するには、 インストール要件ページに記載されているように開発環境を設定する必要があります。

このガイド全体を通して、コード例ではプレースホルダー テキストを使用します。例を実行する前に、これらのプレースホルダーを独自の値に置き換えてください。

以下に例を挙げます。

dek_id := "<Your Base64 DEK ID>"

引用符で囲まれたすべての部分を DEK ID に置き換えます。

dek_id := "abc123"

ページの右側にある Select your languageドロップダウン メニューから、コード例を表示するプログラミング言語の選択します。

Tip

詳細: フルアプリケーション

このチュートリアルの実行可能なアプリケーション コードを表示するには、次のリンクにGoします。

完全な Mongosh アプリケーション

// You are viewing the Mongosh driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the C# driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Golang driver code examples.
// Use the dropdown menu to select a different driver.

重要

Go{0go build または を使用してこのガイドのgo run コードをビルドまたは実行する場合は、 を有効にするために常にcse CSFLEビルド制約を含めてください。ビルド制約を含めた例については、次の shell コマンドを参照してください。

go run -tags cse insert-encrypted-document.go
// You are viewing the Java synchronous driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Node.js driver code examples.
// Use the dropdown menu to select a different driver.
# You are viewing the Python driver code examples.
# Use the dropdown menu to select a different driver.
1

MongoDB ドライバー クライアントをKMIP準拠のキー プロバイダーに接続するには、クライアントの TLS 証明書を受け入れるようにKMIP準拠のキー プロバイダーを構成する必要があります。

クライアント証明書を受け入れる方法については、 KMIP準拠のキー プロバイダーのドキュメントを参照してください。

2

クライアントは TLS 経由で KMIP 準拠のキー プロバイダーに接続し、 KMIP準拠のキー プロバイダーが受け入れるクライアント証明書を提示する必要があります。

make_data_key.js
const tlsOptions = {
kmip: {
tlsCAFile:
"<path to file containing your Certificate Authority certificate>",
tlsCertificateKeyFile: "<path to your client certificate file>",
},
};
MakeDataKey.cs
var tlsOptions = new Dictionary<string, SslSettings>();
var sslSettings = new SslSettings();
var clientCertificate = new X509Certificate2("<path to your pkcs12 client certificate file>");
sslSettings.ClientCertificates = new List<X509Certificate>() {
clientCertificate,
};
tlsOptions.Add(provider, sslSettings);

重要

クライアント証明書は pcks 12形式である必要があります。 次のコマンドで Opensl を使用して証明書を変換できます。

openssl pcks12 -export -out "<new pcks12 certificate>" -in "<certificate to convert>" \
-name "<new certificate name>" -password "<new certificate password>"
make-data-key.go
tlsConfig := make(map[string]*tls.Config)
tlsOpts := map[string]interface{}{
"tlsCertificateKeyFile": "<path to your client certificate file>",
"tlsCAFile": "<path to file containing your Certificate Authority certificate>",
}
kmipConfig, err := options.BuildTLSConfig(tlsOpts)
tlsConfig["kmip"] = kmipConfig

重要

ECDSA キー を持つ証明書を使用する必要があります Go ドライバーを使用する場合

クライアントの TLS 接続を構成するには、次の Java システム プロパティを指定します。

-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.keyStore=<path to pkcs12 KeyStore containing your client certificate>
-Djavax.net.ssl.keyStorePassword=<KeyStore password>

注意

SSLContext を使用したクライアントの構成

SSL コンテキストを使用してクライアント アプリケーションを構成する場合は、 kmsProviderSslContextMap を使用します 使用して複数のドキュメントを挿入できます。

make_data_key.js
const tlsOptions = {
kmip: {
tlsCAFile:
"<path to file containing your Certificate Authority certificate>",
tlsCertificateKeyFile: "<path to your client certificate file>",
},
};
make_data_key.py
tls_options = {
"kmip": {
"tlsCAFile": "<path to file containing your Certificate Authority certificate>",
"tlsCertificateKeyFile": "<path to your client certificate file>",
}
}

アプリケーションで使用している MongoDB ドライバーに対応するタブを選択して、関連するコード サンプルを表示します。

1

encryption.__keyVaultコレクションのkeyAltNamesフィールドに一意のインデックスを作成します。

使用する MongoDB ドライバーに対応するタブを選択します。

make_data_key.js
const uri = "<Your Connection String>";
const keyVaultClient = Mongo(uri);
const keyVaultDB = keyVaultClient.getDB(keyVaultDatabase);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultDB.dropDatabase();
keyVaultDB.createCollection(keyVaultCollection);
const keyVaultColl = keyVaultDB.getCollection(keyVaultCollection);
keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
MakeDataKey.cs
var connectionString = "<Your MongoDB URI>";
var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
var keyVaultClient = new MongoClient(connectionString);
var indexOptions = new CreateIndexOptions<BsonDocument>
{
Unique = true,
PartialFilterExpression = new BsonDocument
{{"keyAltNames", new BsonDocument {{"$exists", new BsonBoolean(true)}}}}
};
var builder = Builders<BsonDocument>.IndexKeys;
var indexKeysDocument = builder.Ascending("keyAltNames");
var indexModel = new CreateIndexModel<BsonDocument>(indexKeysDocument, indexOptions);
var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);
var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName);
keyVaultCollection.Indexes.CreateOne(indexModel);
insert-encrypted-document.go
uri := "<Your MongoDB URI>"
keyVaultClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
if err != nil {
return fmt.Errorf("Connect error for regular client: %v", err)
}
defer func() {
_ = keyVaultClient.Disconnect(context.TODO())
}()
keyVaultDb := "encryption"
keyVaultColl := "__keyVault"
keyVaultNamespace := keyVaultDb + "." + keyVaultColl
keyVaultIndex := mongo.IndexModel{
Keys: bson.D{{"keyAltNames", 1}},
Options: options.Index().
SetUnique(true).
SetPartialFilterExpression(bson.D{
{"keyAltNames", bson.D{
{"$exists", true},
}},
}),
}
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
if err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Drop(context.TODO()); err != nil {
log.Fatalf("Collection.Drop error: %v", err)
}
_, err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Indexes().CreateOne(context.TODO(), keyVaultIndex)
if err != nil {
panic(err)
}
UseDataKey.java
String connectionString = "<Your MongoDB URI>";
String keyVaultDb = "encryption";
String keyVaultColl = "__keyVault";
MongoClient keyVaultClient = MongoClients.create(connectionString);
String encryptedDbName = "medicalRecords";
String encryptedCollName = "patients";
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl).drop();
MongoCollection keyVaultCollection = keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl);
IndexOptions indexOpts = new IndexOptions().partialFilterExpression(new BsonDocument("keyAltNames", new BsonDocument("$exists", new BsonBoolean(true) ))).unique(true);
keyVaultCollection.createIndex(new BsonDocument("keyAltNames", new BsonInt32(1)), indexOpts);
keyVaultClient.close();
make_data_key.js
const uri = "<Your Connection String>";
const keyVaultClient = new MongoClient(uri);
await keyVaultClient.connect();
const keyVaultDB = keyVaultClient.db(keyVaultDatabase);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
await keyVaultDB.dropDatabase();
const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
make_data_key.py
connection_string = "<your connection string here>"
key_vault_coll = "__keyVault"
key_vault_db = "encryption"
key_vault_namespace = f"{key_vault_db}.{key_vault_coll}"
key_vault_client = MongoClient(connection_string)
# Drop the Key Vault Collection in case you created this collection
# in a previous run of this application.
key_vault_client.drop_database(key_vault_db)
key_vault_client[key_vault_db][key_vault_coll].create_index(
[("keyAltNames", ASCENDING)],
unique=True,
partialFilterExpression={"keyAltNames": {"$exists": True}},
)
2
1

KMIP準拠のキー プロバイダーの URI エンドポイントを指定します。

make_data_key.js
const provider = "kmip";
const kmsProviders = {
kmip: {
endpoint: "<endpoint for your KMIP-compliant key provider>",
},
};
MakeDataKey.cs
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "kmip";
var kmipKmsOptions = new Dictionary<string, object>
{
{ "endpoint", "<endpoint for your KMIP-compliant key provider>" },
};
kmsProviders.Add(provider, kmipKmsOptions);
make-data-key.go
provider := "kmip"
kmsProviders := map[string]map[string]interface{}{
provider: {
"endpoint": "<endpoint for your KMIP-compliant key provider>",
},
}
UseDataKey.java
String kmsProvider = "kmip";
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
Map<String, Object> providerDetails = new HashMap<>();
providerDetails.put("endpoint", "<endpoint for your KMIP-compliant key provider>");
kmsProviders.put(kmsProvider, providerDetails);
make_data_key.js
const provider = "kmip";
const kmsProviders = {
kmip: {
endpoint: "<endpoint for your KMIP-compliant key provider>",
},
};
make_data_key.py
provider = "kmip"
kms_providers = {
provider: {"endpoint": "<endpoint for your KMIP-compliant key provider>"}
}
2

次のコードは、 KMIP準拠のキー プロバイダーに CMK の自動生成を要求します。

make_data_key.js
const masterKey = {}; // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
MakeDataKey.cs
DataKeyOptions GetDataKeyOptions(List<string> altNames)
{
var dataKeyOptions = new DataKeyOptions(
alternateKeyNames: altNames,
masterKey: new BsonDocument { } // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
);
return dataKeyOptions;
}
make-data-key.go
masterKey := map[string]interface{}{} // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
UseDataKey.java
BsonDocument masterKeyProperties = new BsonDocument(); // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
make_data_key.js
const masterKey = {}; // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
make_data_key.py
master_key = (
{}
) # an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
3
make_data_key.js
const autoEncryptionOpts = {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
tlsOptions: tlsOptions,
};
const encClient = Mongo(uri, autoEncryptionOpts);
const keyVault = encClient.getKeyVault();
const dek1 = keyVault.createKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey1"],
});
const dek2 = keyVault.createKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey2"],
});
const dek3 = keyVault.createKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey3"],
});
const dek4 = keyVault.createKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey4"],
});
MakeDataKey.cs
var clientEncryptionOptions = new ClientEncryptionOptions(
keyVaultClient,
keyVaultNamespace,
kmsProviders: kmsProviders,
tlsOptions: tlsOptions
);
var clientEncryption = new ClientEncryption(clientEncryptionOptions);
var dataKeyOptions1 = GetDataKeyOptions(new List<string> { "dataKey1" });
var dataKeyOptions2 = GetDataKeyOptions(new List<string> { "dataKey2" });
var dataKeyOptions3 = GetDataKeyOptions(new List<string> { "dataKey3" });
var dataKeyOptions4 = GetDataKeyOptions(new List<string> { "dataKey4" });
BsonBinaryData CreateKeyGetID(DataKeyOptions options)
{
var dateKeyGuid = clientEncryption.CreateDataKey(provider, options, CancellationToken.None);
return new BsonBinaryData(dateKeyGuid, GuidRepresentation.Standard);
}
var dataKeyId1 = CreateKeyGetID(dataKeyOptions1);
var dataKeyId2 = CreateKeyGetID(dataKeyOptions2);
var dataKeyId3 = CreateKeyGetID(dataKeyOptions3);
var dataKeyId4 = CreateKeyGetID(dataKeyOptions4);
make-data-key.go
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(keyVaultNamespace).
SetKmsProviders(kmsProviders).SetTLSConfig(tlsConfig)
clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts)
if err != nil {
return fmt.Errorf("NewClientEncryption error %v", err)
}
defer func() {
_ = clientEnc.Close(context.TODO())
}()
dataKeyOpts1 := options.DataKey().
SetMasterKey(masterKey).
SetKeyAltNames([]string{"demoDataKey1"})
dataKeyID1, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts1)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
dataKeyOpts2 := options.DataKey().
SetMasterKey(masterKey).
SetKeyAltNames([]string{"demoDataKey2"})
dataKeyID2, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts2)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
dataKeyOpts3 := options.DataKey().
SetMasterKey(masterKey).
SetKeyAltNames([]string{"demoDataKey3"})
dataKeyID3, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts3)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
dataKeyOpts4 := options.DataKey().
SetMasterKey(masterKey).
SetKeyAltNames([]string{"demoDataKey4"})
dataKeyID4, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts4)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
UseDataKey.java
String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
List<String> keyAlts1 = new ArrayList<String>();
keyAlts1.add("dataKey1");
BsonBinary dataKeyId1 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions()
.keyAltNames(keyAlts1));
List<String> keyAlts2 = new ArrayList<String>();
keyAlts2.add("dataKey2");
BsonBinary dataKeyId2 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions()
.keyAltNames(keyAlts2));
List<String> keyAlts3 = new ArrayList<String>();
keyAlts3.add("dataKey3");
BsonBinary dataKeyId3 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions()
.keyAltNames(keyAlts3));
List<String> keyAlts4 = new ArrayList<String>();
keyAlts4.add("dataKey4");
BsonBinary dataKeyId4 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions()
.keyAltNames(keyAlts4));
make_data_key.js
const clientEnc = new ClientEncryption(keyVaultClient, {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
tlsOptions,
});
const dek1 = await clientEnc.createDataKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey1"],
});
const dek2 = await clientEnc.createDataKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey2"],
});
const dek3 = await clientEnc.createDataKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey3"],
});
const dek4 = await clientEnc.createDataKey(provider, {
masterKey: masterKey,
keyAltNames: ["dataKey4"],
});
make_data_key.py
client = MongoClient(connection_string)
client_encryption = ClientEncryption(
kms_providers, # pass in the kms_providers variable from the previous step
key_vault_namespace,
client,
CodecOptions(uuid_representation=STANDARD),
kms_tls_options=tls_options,
)
data_key_id_1 = client_encryption.create_data_key(
provider, master_key=master_key, key_alt_names=["dataKey1"]
)
data_key_id_2 = client_encryption.create_data_key(
provider, master_key=master_key, key_alt_names=["dataKey2"]
)
data_key_id_3 = client_encryption.create_data_key(
provider, master_key=master_key, key_alt_names=["dataKey3"]
)
data_key_id_4 = client_encryption.create_data_key(
provider, master_key=master_key, key_alt_names=["dataKey4"]
)

Tip

参照: 完全なコード

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

データ暗号化キーを作成するための完全なコードについては 、 Github リポジトリ を参照してください。

3
1

キーヴォールト コレクションの名前空間としてencryption.__keyVaultを指定します。

insert_encrypted_document.js
const keyVaultDB = "encryption";
const keyVaultColl = "__keyVault";
const keyVaultNamespace = `${keyVaultDB}.${keyVaultColl}`;
const secretDB = "medicalRecords";
const secretCollection = "patients";
InsertEncryptedDocument.cs
var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
insert-encrypted-document.go
keyVaultColl := "__keyVault"
keyVaultDb := "encryption"
keyVaultNamespace := keyVaultDb + "." + keyVaultColl
InsertEncryptedDocument.java
String keyVaultDb = "encryption";
String keyVaultColl = "__keyVault";
String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
insert_encrypted_document.js
const eDB = "encryption";
const eKV = "__keyVault";
const keyVaultNamespace = `${eDB}.${eKV}`;
insert_encrypted_document.py
key_vault_db = "encryption"
key_vault_coll = "__keyVault"
key_vault_namespace = "encryption.__keyVault"
2

kmsProvidersオブジェクトにkmipを指定し、 KMIPに準拠したキー プロバイダーの URI エンドポイントを入力します。

insert_encrypted_document.js
const provider = "kmip";
const kmsProviders = {
kmip: {
endpoint: "<endpoint for your KMIP-compliant key provider>",
},
};
InsertEncryptedDocument.cs
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "kmip";
var kmipKmsOptions = new Dictionary<string, object>
{
{ "endpoint", "<endpoint for your KMIP-compliant key provider>" },
};
kmsProviders.Add(provider, kmipKmsOptions);
insert-encrypted-document.go
provider := "kmip"
kmsProviders := map[string]map[string]interface{}{
provider: {
"endpoint": "<endpoint for your KMIP-compliant key provider>",
},
}
InsertEncryptedDocument.java
String kmsProvider = "kmip";
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
Map<String, Object> providerDetails = new HashMap<>();
providerDetails.put("endpoint", "<endpoint for your KMIP-compliant key provider>");
kmsProviders.put(kmsProvider, providerDetails);
insert_encrypted_document.js
const provider = "kmip";
const kmsProviders = {
kmip: {
endpoint: "<endpoint for your KMIP-compliant key provider>",
},
};
insert_encrypted_document.py
provider = "kmip"
kms_providers = {
provider: {"endpoint": "<endpoint for your KMIP-compliant key provider>"}
}
3
insert_encrypted_document.js
const uri = "<Your Connection String>";
const unencryptedClient = Mongo(uri);
const autoEncryptionOpts = { kmsProviders, keyVaultNamespace };
const encClient = Mongo(uri, autoEncryptionOpts);
const keyVault = encClient.getKeyVault();
const keyVaultClient = unencryptedClient
.getDB(keyVaultDB)
.getCollection(keyVaultColl);
const dek1 = keyVaultClient.findOne({ keyAltNames: "dataKey1" });
const dek2 = keyVaultClient.findOne({ keyAltNames: "dataKey2" });
const dek3 = keyVaultClient.findOne({ keyAltNames: "dataKey3" });
const dek4 = keyVaultClient.findOne({ keyAltNames: "dataKey4" });
const secretDB = "medicalRecords";
const secretColl = "patients";
const encryptedFieldsMap = {
[`${secretDB}.${secretColl}`]: {
fields: [
{
keyId: dek1._id,
path: "patientId",
bsonType: "int",
queries: { queryType: "equality" },
},
{
keyId: dek2._id,
path: "medications",
bsonType: "array",
},
{
keyId: dek3._id,
path: "patientRecord.ssn",
bsonType: "string",
queries: { queryType: "equality" },
},
{
keyId: dek4._id,
path: "patientRecord.billing",
bsonType: "object",
},
],
},
};
InsertEncryptedDocument.cs
var regularClient = new MongoClient(connectionString);
var keyVaultCollection = regularClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName)
.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName);
BsonBinaryData GetKeyId(string altName)
{
var filter = Builders<BsonDocument>.Filter.Eq<BsonString>("keyAltNames", altName);
return keyVaultCollection.Find(filter).First<BsonDocument>()["_id"].AsBsonBinaryData;
}
var dataKeyId1 = GetKeyId("dataKey1");
var dataKeyId2 = GetKeyId("dataKey2");
var dataKeyId3 = GetKeyId("dataKey3");
var dataKeyId4 = GetKeyId("dataKey4");
var encryptedCollectionNamespace = CollectionNamespace.FromFullName("medicalRecords.patients");
var encryptedFieldsMap = new Dictionary<string, BsonDocument>
{
{
encryptedCollectionNamespace.FullName, new BsonDocument
{
{
"fields", new BsonArray
{
new BsonDocument
{
{"keyId", dataKeyId1},
{"path", new BsonString("patientId")},
{"bsonType", new BsonString("int")},
{
"queries", new BsonDocument
{
{"queryType", new BsonString("equality")}
}
}
},
new BsonDocument
{
{"keyId", dataKeyId2},
{"path", new BsonString("medications")},
{"bsonType", new BsonString("array")},
},
new BsonDocument
{
{"keyId", dataKeyId3},
{"path", new BsonString("patientRecord.ssn")},
{"bsonType", new BsonString("string")},
{
"queries", new BsonDocument
{
{"queryType", new BsonString("equality")}
}
}
},
new BsonDocument
{
{"keyId", dataKeyId4},
{"path", new BsonString("patientRecord.billing")},
{"bsonType", new BsonString("object")},
},
}
}
}
}
};
insert-encrypted-document.go
regularClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
if err != nil {
return fmt.Errorf("Connect error for regular client: %v", err)
}
defer func() {
_ = regularClient.Disconnect(context.TODO())
}()
var foundDoc1 bson.M
err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey1"}}).Decode(&foundDoc1)
if err != nil {
panic(err)
}
var dataKeyID1 = foundDoc1["_id"].(primitive.Binary)
var foundDoc2 bson.M
err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey2"}}).Decode(&foundDoc2)
if err != nil {
panic(err)
}
var dataKeyID2 = foundDoc2["_id"].(primitive.Binary)
var foundDoc3 bson.M
err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey3"}}).Decode(&foundDoc3)
if err != nil {
panic(err)
}
var dataKeyID3 = foundDoc3["_id"].(primitive.Binary)
var foundDoc4 bson.M
err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey4"}}).Decode(&foundDoc4)
if err != nil {
panic(err)
}
var dataKeyID4 = foundDoc4["_id"].(primitive.Binary)
encryptedFieldsMap := bson.M{
"medicalRecords.patients": bson.M{
"fields": []bson.M{
{
"path": "patientId",
"bsonType": "int",
"keyId": dataKeyID1,
"queries": []bson.M{
{
"queryType": "equality",
},
},
},
{
"path": "medications",
"bsonType": "array",
"keyId": dataKeyID2,
},
{
"path": "patientRecord.ssn",
"bsonType": "string",
"keyId": dataKeyID3,
"queries": []bson.M{
{
"queryType": "equality",
},
},
},
{
"path": "patientRecord.billing",
"bsonType": "object",
"keyId": dataKeyID4,
},
},
},
}
InsertEncryptedDocument.java
MongoClient regularClient = MongoClients.create(connectionString);
MongoCollection<Document> keyVaultClient = regularClient.getDatabase(keyVaultDb).getCollection(keyVaultColl);
BsonBinary dataKeyId1 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey1")).first().get("_id", Binary.class).getData());
BsonBinary dataKeyId2 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey2")).first().get("_id", Binary.class).getData());
BsonBinary dataKeyId3 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey3")).first().get("_id", Binary.class).getData());
BsonBinary dataKeyId4 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey4")).first().get("_id", Binary.class).getData());
BsonDocument encFields = new BsonDocument().append("fields",
new BsonArray(Arrays.asList(
new BsonDocument().append("keyId", dataKeyId1)
.append("path", new BsonString("patientId"))
.append("bsonType", new BsonString("int"))
.append("queries", new BsonDocument().append("queryType", new BsonString("equality"))),
new BsonDocument().append("keyId", dataKeyId2)
.append("path", new BsonString("medications"))
.append("bsonType", new BsonString("array")),
new BsonDocument().append("keyId", dataKeyId3)
.append("path", new BsonString("patientRecord.ssn"))
.append("bsonType", new BsonString("string"))
.append("queries", new BsonDocument().append("queryType", new BsonString("equality"))),
new BsonDocument().append("keyId", dataKeyId4)
.append("path", new BsonString("patientRecord.billing"))
.append("bsonType", new BsonString("object")))));
Map<String, BsonDocument> encryptedFieldsMap = new HashMap<String, BsonDocument>();
encryptedFieldsMap.put(encryptedNameSpace, encFields);
insert_encrypted_document.js
const uri = "<Your Connection String>";
const unencryptedClient = new MongoClient(uri);
await unencryptedClient.connect();
const keyVaultClient = unencryptedClient.db(eDB).collection(eKV);
const dek1 = await keyVaultClient.findOne({ keyAltNames: "dataKey1" });
const dek2 = await keyVaultClient.findOne({ keyAltNames: "dataKey2" });
const dek3 = await keyVaultClient.findOne({ keyAltNames: "dataKey3" });
const dek4 = await keyVaultClient.findOne({ keyAltNames: "dataKey4" });
const secretDB = "medicalRecords";
const secretCollection = "patients";
const encryptedFieldsMap = {
[`${secretDB}.${secretCollection}`]: {
fields: [
{
keyId: dek1._id,
path: "patientId",
bsonType: "int",
queries: { queryType: "equality" },
},
{
keyId: dek2._id,
path: "medications",
bsonType: "array",
},
{
keyId: dek3._id,
path: "patientRecord.ssn",
bsonType: "string",
queries: { queryType: "equality" },
},
{
keyId: dek4._id,
path: "patientRecord.billing",
bsonType: "object",
},
],
},
};
insert_encrypted_document.py
connection_string = "<your connection string here>"
unencryptedClient = MongoClient(connection_string)
keyVaultClient = unencryptedClient[key_vault_db][key_vault_coll]
data_key_id_1 = keyVaultClient.find_one({"keyAltNames": "dataKey1"})["_id"]
data_key_id_2 = keyVaultClient.find_one({"keyAltNames": "dataKey2"})["_id"]
data_key_id_3 = keyVaultClient.find_one({"keyAltNames": "dataKey3"})["_id"]
data_key_id_4 = keyVaultClient.find_one({"keyAltNames": "dataKey4"})["_id"]
encrypted_db_name = "medicalRecords"
encrypted_coll_name = "patients"
encrypted_fields_map = {
f"{encrypted_db_name}.{encrypted_coll_name}": {
"fields": [
{
"keyId": data_key_id_1,
"path": "patientId",
"bsonType": "int",
"queries": {"queryType": "equality"},
},
{
"keyId": data_key_id_2,
"path": "medications",
"bsonType": "array",
},
{
"keyId": data_key_id_3,
"path": "patientRecord.ssn",
"bsonType": "string",
"queries": {"queryType": "equality"},
},
{
"keyId": data_key_id_4,
"path": "patientRecord.billing",
"bsonType": "object",
},
],
},
}

Tip

スキーマの詳細読み取り

このステップで使用するスキーマを構築する方法について詳しくは、暗号化スキーマのガイドを参照してください。

暗号化スキーマでサポートされているすべての暗号化ルールのリストを表示するには、 CSFLE 暗号化スキーマのガイドを参照してください。

4
InsertEncryptedDocument.cs
var extraOptions = new Dictionary<string, object>()
{
{ "cryptSharedLibPath", "<path to crypt_shared library>" },
};
insert-encrypted-document.go
extraOptions := map[string]interface{}{
"cryptSharedLibPath": "<Your Crypt Shared lib Path>",
}
InsertEncryptedDocument.java
Map<String, Object> extraOptions = new HashMap<String, Object>();
extraOptions.put("cryptSharedLibPath", "<path to crypt_shared>");
insert_encrypted_document.js
const extraOptions = {
cryptSharedLibPath: "<path to FLE Shared Library>",
};
insert_encrypted_document.py
auto_encryption = AutoEncryptionOpts(
kms_providers,
key_vault_namespace,
encrypted_fields_map=encrypted_fields_map,
kms_tls_options=tls_options,
schema_map=None,
crypt_shared_lib_path="<path to FLE Shared Library>",
)
5

次の自動暗号化設定を使用して MongoDB クライアント オブジェクトをインスタンス化します。

insert_encrypted_document.js
const autoEncryptionOptions = {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
bypassQueryAnalysis: false,
encryptedFieldsMap: encryptedFieldsMap,
tlsOptions: tlsOptions,
};
const encryptedClient = Mongo(uri, autoEncryptionOptions);
const encryptedColl = encryptedClient
.getDB(secretDB)
.getCollection(secretColl);
const unencryptedColl = unencryptedClient
.getDB(secretDB)
.getCollection(secretColl);
InsertEncryptedDocument.cs
var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace,
kmsProviders,
encryptedFieldsMap: encryptedFieldsMap,
extraOptions: extraOptions,
tlsOptions: tlsOptions
);
clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
var secureClient = new MongoClient(clientSettings);
insert-encrypted-document.go
autoEncryptionOpts := options.AutoEncryption().
SetKmsProviders(kmsProviders).
SetKeyVaultNamespace(keyVaultNamespace).
SetEncryptedFieldsMap(encryptedFieldsMap).
SetExtraOptions(extraOptions).SetTLSConfig(tlsConfig)
secureClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri).SetAutoEncryptionOptions(autoEncryptionOpts))
if err != nil {
return fmt.Errorf("Connect error for encrypted client: %v", err)
}
defer func() {
_ = secureClient.Disconnect(context.TODO())
}()
InsertEncryptedDocument.java
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.encryptedFieldsMap(encryptedFieldsMap)
.extraOptions(extraOptions)
.build())
.build();
MongoClient mongoClientSecure = MongoClients.create(clientSettings);
insert_encrypted_document.js
const encryptedClient = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
extraOptions: extraOptions,
encryptedFieldsMap: encryptedFieldsMap,
tlsOptions,
},
});
await encryptedClient.connect();
insert_encrypted_document.py
secure_client = MongoClient(connection_string, auto_encryption_opts=auto_encryption)
4

QE対応のMongoClientインスタンスで、次のコード スニペットを使用して暗号化されたドキュメントをmedicalRecords.patients名前空間に挿入します。

encryptedColl.insertOne({
firstName: "Jon",
lastName: "Doe",
patientId: 12345678,
address: "157 Electric Ave.",
patientRecord: {
ssn: "987-65-4320",
billing: {
type: "Visa",
number: "4111111111111111",
},
},
medications: ["Atorvastatin", "Levothyroxine"],
});
InsertEncryptedDocument.cs
var sampleDocument = new BsonDocument
{
{"firstName", "Jon"},
{"lastName", "Doe"},
{"patientId", 12345678},
{"address", "157 Electric Ave."},
{
"medications", new BsonArray
{
new BsonString("Atorvastatin"),
new BsonString("Levothyroxine")
}
},
{
"patientRecord", new BsonDocument
{
{"ssn", new BsonString("987-65-4320")},
{
"billing", new BsonDocument
{
{"type", new BsonString("Visa")},
{"number", "4111111111111111"}
}
}
}
}
};
var secureCollection = secureClient.GetDatabase(encryptedCollectionNamespace.DatabaseNamespace.DatabaseName)
.GetCollection<BsonDocument>(encryptedCollectionNamespace.CollectionName);
secureCollection.InsertOne(sampleDocument);
insert-encrypted-document.go
test_patient := map[string]interface{}{
"firstName": "Jon",
"lastName": "Doe",
"patientId": 12345678,
"address": "157 Electric Ave.",
"medications": []string{"Atorvastatin", "Levothyroxine"},
"patientRecord": map[string]interface{}{
"ssn": "987-65-4320",
"billing": map[string]interface{}{
"type": "Visa",
"number": "4111111111111111",
},
},
}
if _, err := secureClient.Database(dbName).Collection(collName).InsertOne(context.TODO(), test_patient); err != nil {
return fmt.Errorf("InsertOne error: %v", err)
}

注意

未加工の BSON ドキュメントを作成する代わりに、 bsonタグを含む構造体をドライバーに直接渡してエンコードできます。

InsertEncryptedDocument.java
ArrayList<String> medications = new ArrayList<>();
medications.add("Atorvastatin");
medications.add("Levothyroxine");
Document patientRecord = new Document()
.append("ssn", "987-65-4320")
.append("billing", new Document().append("type", "Visa").append("number", "4111111111111111"));
Document patient = new Document()
.append("firstName", "Jon")
.append("lastName", "Doe")
.append("patientId", 12345678)
.append("address", "AB+")
.append("medications", medications)
.append("patientRecord", patientRecord);
mongoClientSecure.getDatabase(encryptedDbName).getCollection(encryptedCollName).insertOne(patient);
insert_encrypted_document.js
const encryptedColl = encryptedClient
.db(secretDB)
.collection(secretCollection);
await encryptedColl.insertOne({
firstName: "Jon",
lastName: "Doe",
patientId: 12345678,
address: "157 Electric Ave.",
patientRecord: {
ssn: "987-65-4320",
billing: {
type: "Visa",
number: "4111111111111111",
},
},
medications: ["Atorvastatin", "Levothyroxine"],
});
insert_encrypted_document.py
encrypted_coll = secure_client[encrypted_db_name][encrypted_coll_name]
encrypted_coll.insert_one(
{
"firstName": "Jon",
"lastName": "Doe",
"patientId": 12345678,
"address": "157 Electric Ave.",
"patientRecord": {
"ssn": "987-65-4320",
"billing": {
"type": "Visa",
"number": "4111111111111111",
},
},
"medications": ["Atorvastatin", "Levothyroxine"],
}
)

ドキュメントを挿入すると、Queryable Encryption 対応のクライアントはドキュメントのフィールドを次のように暗号化します。

{
"_id": { "$oid": "<_id value>" },
"firstName": "Jon",
"lastName": "Doe",
"patientId": {
"$binary": {
"base64": "<ciphertext>",
"subType": "06"
}
},
"address": "157 Electric Ave.",
"patientRecord": {
"ssn": {
"$binary": {
"base64": "<ciphertext>",
"subType": "06"
}
},
"billing": {
"$binary": {
"base64": "<ciphertext>",
"subType": "06"
}
}
},
"medications": {
"$binary": {
"base64": "<ciphertext>",
"subType": "06"
}
},
"__safeContent__": [
{
"$binary": {
"base64": "<ciphertext>",
"subType": "00"
}
},
{
"$binary": {
"base64": "<ciphertext>",
"subType": "00"
}
}
]
}

警告

MongoDB_ENUS_JAJP フィールドを変更しないでください

__safeContent__フィールドは Queryable Encryption に必須です。 このフィールドの内容は変更しないでください。

Tip

参照: 完全なコード

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照して ください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

5

このガイドの「暗号化されたフィールドを使用してドキュメントを挿入する 」ステップで挿入した暗号化されたドキュメントを取得します。

QE の機能を示すために、次のコード スニペットは、自動 QE 用に構成されたクライアントと、自動 QE 用 に構成されていないクライアントを使用して、ドキュメントに対してクエリを実行します。

insert_encrypted_document.js
console.log("Finding a document with regular (non-encrypted) client.");
console.log(unencryptedColl.findOne({ firstName: /Jon/ }));
console.log(
"Finding a document with encrypted client, searching on an encrypted field"
);
console.log(encryptedColl.findOne({ "patientRecord.ssn": "987-65-4320" }));
InsertEncryptedDocument.cs
Console.WriteLine("Finding a document with regular (non-encrypted) client.");
var filter = Builders<BsonDocument>.Filter.Eq("firstName", "Jon");
var regularClientEncryptedCollection = regularClient.GetDatabase(encryptedCollectionNamespace.DatabaseNamespace.DatabaseName)
.GetCollection<BsonDocument>(encryptedCollectionNamespace.CollectionName);
var regularResult = regularClientEncryptedCollection.Find(filter).First();
Console.WriteLine($"\n{regularResult}\n");
Console.WriteLine("Finding a document with encrypted client, searching on an encrypted field");
var encryptedFieldFilter = Builders<BsonDocument>.Filter.Eq("patientRecord.ssn", "987-65-4320");
var secureResult = secureCollection.Find(encryptedFieldFilter).First();
Console.WriteLine($"\n{secureResult}\n");
insert-encrypted-document.go
fmt.Println("Finding a document with regular (non-encrypted) client.")
var resultRegular bson.M
err = regularClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"firstName", "Jon"}}).Decode(&resultRegular)
if err != nil {
panic(err)
}
outputRegular, err := json.MarshalIndent(resultRegular, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputRegular)
fmt.Println("Finding a document with encrypted client, searching on an encrypted field")
var resultSecure bson.M
err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{bson.E{"patientRecord.ssn", "987-65-4320"}}).Decode(&resultSecure)
if err != nil {
panic(err)
}
outputSecure, err := json.MarshalIndent(resultSecure, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputSecure)
InsertEncryptedDocument.java
System.out.println("Finding a document with regular (non-encrypted) client.");
Document docRegular = regularClient.getDatabase(encryptedDbName).getCollection(encryptedCollName).find(eq("firstName", "Jon")).first();
System.out.println(docRegular.toJson());
System.out.println("Finding a document with encrypted client, searching on an encrypted field");
Document docSecure = mongoClientSecure.getDatabase(encryptedDbName).getCollection(encryptedCollName).find(eq("patientRecord.ssn", "987-65-4320")).first();
System.out.println(docSecure.toJson());
insert_encrypted_document.js
console.log("Finding a document with regular (non-encrypted) client.");
console.log(await unencryptedColl.findOne({ firstName: /Jon/ }));
console.log(
"Finding a document with encrypted client, searching on an encrypted field"
);
console.log(
await encryptedColl.findOne({ "patientRecord.ssn": "987-65-4320" })
);
insert_encrypted_document.py
print("Finding a document with regular (non-encrypted) client.")
pprint.pprint(
unencryptedClient[encrypted_db_name][encrypted_coll_name].find_one(
{"firstName": "Jon"}
)
)
print("Finding a document with encrypted client, searching on an encrypted field")
pprint.pprint(encrypted_coll.find_one({"patientRecord.ssn": "987-65-4320"}))

上記のコード スニペットの出力は次のようになります。

Finding a document with regular (non-encrypted) client.
{
_id: new ObjectId("628eabeb37590e84ea742665"),
firstName: 'Jon',
lastName: 'Doe',
patientId: new Binary(Buffer.from("0798810acc0f4f46c9a76883cee80fca12102e9ddcbcdae46a821fa108a8155a850f2d0919475b6531ada68973d436a199b537a05a98a708c36d2bfec4979d59cbe66878865ce19e392d3e4789d309bdacc336e32efcc851806ae0a41b355288c10d01e39147e1c40d919c41913a0c9d2d3fad0d0d1d2873c4fc82c6c22f27b517df5f3131b331b96ed16a7c5cf89e09082a2d898c2dcd73da91d08760ba74a70077b2d0fdbbe1eea75655a19fcc397812325ad40b102cbd16b8d36b22e11e3f93404f24a8ff68cfdec3c22b0e787cb30078a5227b2a", "hex"), 6),
address: '157 Electric Ave.',
patientRecord: {
ssn: new Binary(Buffer.from("07e8b69630c32f4a00a542af768f8abcf50223edd812ff20b0ecb046ee1a9f5a0eef8d85d99cd26076411129942752516ee605c55aadce73f3d44d81ea6ddbbb8134b108a9deb40d8cab9cb4f08ef210ab0c9d2ea4347f9d235b861baf29751e60abcf059eb5c120305bd5ac05a4e07ac8ccfa6d37283f4cdbfeb7a8accb65b71857d486b5cf55e354d6a95e287d9e2dd65f3f9d9c4c9d0bdb1f26c4bd549d7be77db81796be293e08b2223bac67b212423c4e06568578b5bd7a3c33cedc1b291bcda0b27e005144d344563711a489f24b8e9b65bbb721d3a0e9d9b227a0cec0cbad", "hex"), 6),
billing: new Binary(Buffer.from("06808ae69d4caa49cf90bb688f386f097f03f870a7b8fcebb1980c9ee5488b1f0f68558fc2163adcd92d00ea5f349f56ed34e7b391f54c48ed2760b4bde73022fc818dc7486a4e046b92ce9c82e00333c7779d9d6bb476713a20632b593b7de54812662cfc4d174d05451d3f4195514e12edba", "hex"), 6)
},
medications: new Binary(Buffer.from("06665ec15d38254dc4aa16da856789d33404f27bfea53e0d2fa4deaff166989ab33f469644d89c29112d33b41dbe54ec2d89c43f3de52cdc5d454e8694046216f533614fa7b42b7c5406d6518f7ed8f9e3ce52fda6c8b2146d0f8cc51e21a3467183697e1735a9f60c18e173c1916101", "hex"), 6),
__safeContent__: [
new Binary(Buffer.from("3044b134ad0f7c8a90dab1e05bb8b296a8ede540796bd7403ab47693cdba1b26", "hex"), 0),
new Binary(Buffer.from("a22ddf9a5657cdd56bef72febbba44371899e6486962a1c07d682082c4e65712", "hex"), 0)
]
}
Finding a document with encrypted client, searching on an encrypted field
{
_id: new ObjectId("628eaca1dcf9b63e2f43162d"),
firstName: 'Jon',
lastName: 'Doe',
patientId: 12345678,
address: '157 Electric Ave.',
patientRecord: {
ssn: '987-65-4320',
billing: { type: 'Visa', number: '4111111111111111' }
},
medications: [ 'Atorvastatin', 'Levothyroxine' ],
__safeContent__: [
new Binary(Buffer.from("fbdc6cfe3b4659693650bfc60baced27dcb42b793efe09da0ded54d60a9d5a1f", "hex"), 0),
new Binary(Buffer.from("0f92ff92bf904a858ef6fd5b1e508187f523e791f51d8b64596461b38ebb1791", "hex"), 0)
]
}

Tip

参照: 完全なコード

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照して ください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

暗号化されたドキュメントを挿入するための完全なコードについては 、 Github リポジトリ を参照してください。

このガイドで言及されているトピックについて詳しくは、次のリンクを参照してください。

戻る

Use GCP