クライアント側の暗号化
v 4.2以降、 MongoDB はクライアント側の暗号化をサポートしています。 クライアント側暗号化を使用すると、管理者や開発者は、MongoDB の他の暗号化機能を提供するだけでなく、特定のデータ フィールドを暗号化できます。
フィールドレベルの暗号化を使用すると、開発者はサーバー側の設定やディレクティブなしで、クライアント側のフィールドを暗号化できます。 クライアント側のフィールドレベル暗号化は、暗号化されたデータをサーバー管理者などの権限のないユーザーが読み取れることをアプリケーションが保証する必要があるワークロードをサポートします。
重要
このガイドでは、 クイック スタート プライマリで説明されている Subscriber
の実装を使用します。
インストール
プロジェクトでフィールドレベルの暗号化の使用を開始するには、依存関係管理システムを使用することをお勧めします。 フィールドレベルの暗号化には、ドライバーに加えて追加のパッケージが必要です。
注意
Java Reactive Streams ドライバーをインストールする方法の詳細については、インストール ガイド を参照してください。
libmongocrypt
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' }
mongocryptd の構成
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());