Docs Menu
Docs Home
/ / /
Java Reactive Streams ドライバー
/

クライアント側の暗号化

項目一覧

  • インストール
  • libmongocrypt
  • mongocryptd の構成
  • 明示的な暗号化と復号化
  • 明示的な暗号化と自動復号化

v 4.2以降、 MongoDB はクライアント側の暗号化をサポートしています。 クライアント側暗号化を使用すると、管理者や開発者は、MongoDB の他の暗号化機能を提供するだけでなく、特定のデータ フィールドを暗号化できます。

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

重要

このガイドでは、 クイック スタート プライマリで説明されている Subscriberの実装を使用します。

プロジェクトでフィールドレベルの暗号化の使用を開始するには、依存関係管理システムを使用することをお勧めします。 フィールドレベルの暗号化には、ドライバーに加えて追加のパッケージが必要です。

注意

Java Reactive Streams ドライバーをインストールする方法の詳細については、インストール ガイド を参照してください。

libmongocryptバインディングを含む別の JAR ファイルがあります。

Maven を使用している場合 パッケージを管理するには、次のエントリをpom.xml 依存関係リストに追加します。

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-crypt</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>

Gradle を使用している場合 パッケージを管理するには、次のエントリを 依存関係リストに追加します。

dependencies {
implementation 'org.mongodb:mongodb-crypt:1.2.1'
}

libmongocryptバインディングでは、 mongocryptdのデーモンまたは プロセスが実行されている必要があります。 特定のデーモンまたはプロセス URI は、 extraOptions設定でmongocryptdURIを設定することで、 AutoEncryptionSettingsクラスで構成できます。

次の例は、キーとスキーマが MongoDB ですでに作成されていることを前提としているサンプル アプリです。 この例ではローカル キーを使用していますが、 Amazon Web Services 、 Azure 、 GCP KMSを使用することもできます。 encryptedFieldフィールドのデータは、挿入時に自動的に暗号化され、クライアント側で find を使用するときに復号化されます。

コード例は ClientSideEncryptionSimpleTour.java からのものです ドライバー ソースGithub コード リポジトリ内のファイル。

import com.mongodb.AutoEncryptionSettings;
import com.mongodb.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import com.mongodb.reactivestreams.client.MongoCollection;
import org.bson.Document;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
public class ClientSideEncryptionSimpleTour {
public static void main(final String[] args) {
// This would have to be the same master key as was used to create the encryption key
final byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
put("local", new HashMap<String, Object>() {{
put("key", localMasterKey);
}});
}};
String keyVaultNamespace = "admin.datakeys";
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
MongoClientSettings clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(autoEncryptionSettings)
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
collection.drop().subscribe(successSubscriber);
successSubscriber.await();
successSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", "123456789")).subscribe(successSubscriber);
successSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new PrintDocumentSubscriber();
collection.find().first().subscribe(documentSubscriber);
documentSubscriber.await();
}
}

注意

自動暗号化はEnterprise のみの機能です。

次の例は、AutoEncryptionSettings インスタンスを構成して新しいキーを作成し、 JSON schemaマップを設定する方法を示しています。

コード例は ClientSideEncryptionAutoEncryptionSettingsTour.java Githubからのものです ドライバー ソース コード リポジトリ内のファイル。

import com.mongodb.ClientEncryptionSettings;
import com.mongodb.ConnectionString;
import com.mongodb.client.model.vault.DataKeyOptions;
import com.mongodb.client.vault.ClientEncryption;
import com.mongodb.client.vault.ClientEncryptions;
import org.bson.BsonBinary;
import org.bson.BsonDocument;
import java.util.Base64;
...
String keyVaultNamespace = "admin.datakeys";
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost"))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
final String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
final String dbName = "test";
final String collName = "coll";
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(new HashMap<String, BsonDocument>() {{
put(dbName + "." + collName,
// Need a schema that references the new data key
BsonDocument.parse("{"
+ " properties: {"
+ " encryptedField: {"
+ " encrypt: {"
+ " keyId: [{"
+ " \"$binary\": {"
+ " \"base64\": \"" + base64DataKeyId + "\","
+ " \"subType\": \"04\""
+ " }"
+ " }],"
+ " bsonType: \"string\","
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\""
+ " }"
+ " }"
+ " },"
+ " \"bsonType\": \"object\""
+ "}"));
}}).build();

明示的な暗号化と復号化は MongoDB Community の機能であり、 mongocryptdプロセスは使用されません。 明示的な暗号化はClientEncryptionクラスによって提供されます。

コード例は ClientSideEncryptionExplitEncryptionAndDecryptionTour.java からのものです ドライバー ソースGithub コード リポジトリ内のファイル。

// This would have to be the same master key as was used to create the encryption key
final byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
put("local", new HashMap<String, Object>() {{
put("key", localMasterKey);
}});
}};
MongoNamespace keyVaultNamespace = new MongoNamespace("encryption.testKeyVault");
MongoClientSettings clientSettings = MongoClientSettings.builder().build();
MongoClient mongoClient = MongoClients.create(clientSettings);
// Set up the key vault for this example
MongoCollection<Document> keyVaultCollection = mongoClient
.getDatabase(keyVaultNamespace.getDatabaseName())
.getCollection(keyVaultNamespace.getCollectionName());
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
keyVaultCollection.drop().subscribe(successSubscriber);
successSubscriber.await();
// Ensure that two data keys cannot share the same keyAltName.
ObservableSubscriber<String> indexSubscriber = new OperationSubscriber<>();
keyVaultCollection.createIndex(Indexes.ascending("keyAltNames"),
new IndexOptions().unique(true)
.partialFilterExpression(Filters.exists("keyAltNames")))
.subscribe(indexSubscriber);
indexSubscriber.await();
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
successSubscriber = new OperationSubscriber<>();
collection.drop().subscribe(successSubscriber);
successSubscriber.await();
// Create the ClientEncryption instance
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost"))
.build())
.keyVaultNamespace(keyVaultNamespace.getFullName())
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
// Explicitly encrypt a field
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
.subscribe(insertOneSubscriber);
insertOneSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
collection.find().first().subscribe(documentSubscriber);
Document doc = documentSubscriber.get().get(0);
System.out.println(doc.toJson());
// Explicitly decrypt the field
System.out.println(
clientEncryption.decrypt(new BsonBinary(doc.get("encryptedField", Binary.class).getData()))
);

ただし、自動暗号化には MongoDB 4.2 Enterprise または MongoDB 4.2 800} が必要です Atlas クラスターでは、すべてのユーザーに対して自動復号化がサポートされています。 自動暗号化を使用せずに自動復号化を構成するには、 bypassAutoEncryption(true)を設定します。

コード例は ClientSideEncryptionExplitEncryptionOnlyTour.java Githubからのものです ドライバー ソース コード リポジトリ内のファイル。

...
MongoClientSettings clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace.getFullName())
.kmsProviders(kmsProviders)
.bypassAutoEncryption(true)
.build())
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
...
// Explicitly encrypt a field
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
.subscribe(insertOneSubscriber);
insertOneSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
collection.find().first().subscribe(documentSubscriber);
Document doc = documentSubscriber.get().get(0);
System.out.println(doc.toJson());

戻る

読み取り操作