Skip to content

Commit eccc8e5

Browse files
committed
encrypt fields embeddings
1 parent ce58485 commit eccc8e5

File tree

4 files changed

+44
-342
lines changed

4 files changed

+44
-342
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. code-block:: groovy
2+
3+
dependencies {
4+
implementation 'org.mongodb:mongodb-crypt:{+full-version+}'
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. code-block:: xml
2+
3+
<dependencies>
4+
<dependency>
5+
<groupId>org.mongodb</groupId>
6+
<artifactId>mongodb-crypt</artifactId>
7+
<version>{+full-version+}</version>
8+
</dependency>
9+
</dependencies>

source/security/encrypt.txt

Lines changed: 26 additions & 342 deletions
Original file line numberDiff line numberDiff line change
@@ -1,344 +1,28 @@
11
.. _javars-encrypt:
22

3-
======================
4-
Client-Side Encryption
5-
======================
6-
7-
.. facet::
8-
:name: genre
9-
:values: reference
10-
11-
.. meta::
12-
:keywords: code example, encrypt data, decrypt data
13-
14-
.. contents:: On this page
15-
:local:
16-
:backlinks: none
17-
:depth: 2
18-
:class: singlecol
19-
20-
Starting in v4.2, MongoDB supports client-side encryption. Client-side
21-
encryption allows administrators and developers to encrypt specific data
22-
fields in addition to providing other MongoDB encryption features.
23-
24-
With field-level encryption, developers can encrypt fields on the client-side
25-
without any server-side configuration or directives. Client-side field
26-
level encryption supports workloads where applications must guarantee
27-
that unauthorized parties, including server administrators, cannot
28-
read the encrypted data.
29-
30-
.. include:: /includes/subscriber-note.rst
31-
32-
Installation
33-
------------
34-
35-
The recommended way to get started using field-level encryption in
36-
your project is by using a dependency management system. Field-level
37-
encryption requires additional packages in addition to the
38-
driver.
39-
40-
.. note::
41-
42-
For instructions about how to install the {+driver-short+},
43-
see the :ref:`Get Started tutorial <java-rs-getting-started>`.
44-
45-
libmongocrypt
46-
~~~~~~~~~~~~~
47-
48-
There is a separate JAR file containing ``libmongocrypt`` bindings.
49-
50-
.. tabs::
51-
52-
.. tab:: Maven
53-
:tabid: maven-installation
54-
55-
If you are using `Maven <https://maven.apache.org/>`__ to manage your
56-
packages, add the following entry to your ``pom.xml`` dependencies list:
57-
58-
.. code-block:: xml
59-
60-
<dependencies>
61-
<dependency>
62-
<groupId>org.mongodb</groupId>
63-
<artifactId>mongodb-crypt</artifactId>
64-
<version>1.2.1</version>
65-
</dependency>
66-
</dependencies>
67-
68-
.. tab:: Gradle
69-
:tabid: gradle-installation
70-
71-
If you are using `Gradle <https://gradle.org/>`__ to manage your
72-
packages, add the following entry to your dependencies list:
73-
74-
.. code-block:: java
75-
76-
dependencies {
77-
implementation 'org.mongodb:mongodb-crypt:1.2.1'
78-
}
79-
80-
mongocryptd Configuration
81-
~~~~~~~~~~~~~~~~~~~~~~~~~
82-
83-
The ``libmongocrypt`` bindings require the ``mongocryptd`` daemon/process to be
84-
running. A specific daemon/process URI can be configured in the
85-
``AutoEncryptionSettings`` class by setting ``mongocryptdURI`` in the
86-
``extraOptions`` setting.
87-
88-
Examples
89-
--------
90-
91-
The following example is a sample app that assumes the key and schema have
92-
already been created in MongoDB. The example uses a local key, but you
93-
can also use the AWS/Azure/GCP Key Management Service. The data in
94-
the ``encryptedField`` field is automatically encrypted on the insert
95-
and decrypted when using find on the client side.
96-
97-
The code example is from the `ClientSideEncryptionSimpleTour.java
98-
<{+driver-source-gh+}/blob/master/driver-reactive-streams/src/examples/reactivestreams/tour/ClientSideEncryptionSimpleTour.java>`__
99-
file in the driver source code GitHub repository.
100-
101-
.. code-block:: java
102-
103-
import com.mongodb.AutoEncryptionSettings;
104-
import com.mongodb.MongoClientSettings;
105-
import com.mongodb.reactivestreams.client.MongoClient;
106-
import com.mongodb.reactivestreams.client.MongoClients;
107-
import com.mongodb.reactivestreams.client.MongoCollection;
108-
import org.bson.Document;
109-
110-
import java.security.SecureRandom;
111-
import java.util.HashMap;
112-
import java.util.Map;
113-
114-
public class ClientSideEncryptionSimpleTour {
115-
116-
public static void main(final String[] args) {
117-
118-
// This would have to be the same master key as was used to create the encryption key
119-
final byte[] localMasterKey = new byte[96];
120-
new SecureRandom().nextBytes(localMasterKey);
121-
122-
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
123-
put("local", new HashMap<String, Object>() {{
124-
put("key", localMasterKey);
125-
}});
126-
}};
127-
128-
String keyVaultNamespace = "admin.datakeys";
129-
130-
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
131-
.keyVaultNamespace(keyVaultNamespace)
132-
.kmsProviders(kmsProviders)
133-
.build();
134-
135-
MongoClientSettings clientSettings = MongoClientSettings.builder()
136-
.autoEncryptionSettings(autoEncryptionSettings)
137-
.build();
138-
139-
MongoClient mongoClient = MongoClients.create(clientSettings);
140-
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
141-
142-
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
143-
collection.drop().subscribe(successSubscriber);
144-
successSubscriber.await();
145-
146-
successSubscriber = new OperationSubscriber<>();
147-
collection.insertOne(new Document("encryptedField", "123456789")).subscribe(successSubscriber);
148-
successSubscriber.await();
149-
150-
ObservableSubscriber<Document> documentSubscriber = new PrintDocumentSubscriber();
151-
collection.find().first().subscribe(documentSubscriber);
152-
documentSubscriber.await();
153-
}
154-
}
155-
156-
.. note::
157-
158-
Automatic encryption is an **enterprise only** feature.
159-
160-
The following example shows how to configure the
161-
``AutoEncryptionSettings`` instance to create a new key and set the
162-
JSON schema map.
163-
164-
The code example is from the `ClientSideEncryptionAutoEncryptionSettingsTour.java
165-
<{+driver-source-gh+}/blob/master/driver-reactive-streams/src/examples/reactivestreams/tour/ClientSideEncryptionAutoEncryptionSettingsTour.java>`__
166-
file in the driver source code GitHub repository.
167-
168-
.. code-block:: java
169-
170-
import com.mongodb.ClientEncryptionSettings;
171-
import com.mongodb.ConnectionString;
172-
import com.mongodb.client.model.vault.DataKeyOptions;
173-
import com.mongodb.client.vault.ClientEncryption;
174-
import com.mongodb.client.vault.ClientEncryptions;
175-
import org.bson.BsonBinary;
176-
import org.bson.BsonDocument;
177-
178-
import java.util.Base64;
179-
180-
...
181-
182-
String keyVaultNamespace = "admin.datakeys";
183-
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
184-
.keyVaultMongoClientSettings(MongoClientSettings.builder()
185-
.applyConnectionString(new ConnectionString("mongodb://localhost"))
186-
.build())
187-
.keyVaultNamespace(keyVaultNamespace)
188-
.kmsProviders(kmsProviders)
189-
.build();
190-
191-
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
192-
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
193-
final String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
194-
195-
final String dbName = "test";
196-
final String collName = "coll";
197-
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
198-
.keyVaultNamespace(keyVaultNamespace)
199-
.kmsProviders(kmsProviders)
200-
.schemaMap(new HashMap<String, BsonDocument>() {{
201-
put(dbName + "." + collName,
202-
// Need a schema that references the new data key
203-
BsonDocument.parse("{"
204-
+ " properties: {"
205-
+ " encryptedField: {"
206-
+ " encrypt: {"
207-
+ " keyId: [{"
208-
+ " \"$binary\": {"
209-
+ " \"base64\": \"" + base64DataKeyId + "\","
210-
+ " \"subType\": \"04\""
211-
+ " }"
212-
+ " }],"
213-
+ " bsonType: \"string\","
214-
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\""
215-
+ " }"
216-
+ " }"
217-
+ " },"
218-
+ " \"bsonType\": \"object\""
219-
+ "}"));
220-
}}).build();
221-
222-
Explicit Encryption and Decryption
223-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
224-
225-
Explicit encryption and decryption is a MongoDB community feature and
226-
does not use the ``mongocryptd`` process. Explicit encryption is
227-
provided by the ``ClientEncryption`` class.
228-
229-
The code example is from the `ClientSideEncryptionExplicitEncryptionAndDecryptionTour.java
230-
<{+driver-source-gh+}/blob/master/driver-reactive-streams/src/examples/reactivestreams/tour/ClientSideEncryptionExplicitEncryptionAndDecryptionTour.java>`__
231-
file in the driver source code GitHub repository.
232-
233-
.. code-block:: java
234-
235-
// This would have to be the same master key as was used to create the encryption key
236-
final byte[] localMasterKey = new byte[96];
237-
new SecureRandom().nextBytes(localMasterKey);
238-
239-
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
240-
put("local", new HashMap<String, Object>() {{
241-
put("key", localMasterKey);
242-
}});
243-
}};
244-
245-
MongoNamespace keyVaultNamespace = new MongoNamespace("encryption.testKeyVault");
246-
247-
MongoClientSettings clientSettings = MongoClientSettings.builder().build();
248-
MongoClient mongoClient = MongoClients.create(clientSettings);
249-
250-
// Set up the key vault for this example
251-
MongoCollection<Document> keyVaultCollection = mongoClient
252-
.getDatabase(keyVaultNamespace.getDatabaseName())
253-
.getCollection(keyVaultNamespace.getCollectionName());
254-
255-
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
256-
keyVaultCollection.drop().subscribe(successSubscriber);
257-
successSubscriber.await();
258-
259-
// Ensure that two data keys cannot share the same keyAltName.
260-
ObservableSubscriber<String> indexSubscriber = new OperationSubscriber<>();
261-
keyVaultCollection.createIndex(Indexes.ascending("keyAltNames"),
262-
new IndexOptions().unique(true)
263-
.partialFilterExpression(Filters.exists("keyAltNames")))
264-
.subscribe(indexSubscriber);
265-
indexSubscriber.await();
266-
267-
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
268-
successSubscriber = new OperationSubscriber<>();
269-
collection.drop().subscribe(successSubscriber);
270-
successSubscriber.await();
271-
272-
// Create the ClientEncryption instance
273-
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
274-
.keyVaultMongoClientSettings(MongoClientSettings.builder()
275-
.applyConnectionString(new ConnectionString("mongodb://localhost"))
276-
.build())
277-
.keyVaultNamespace(keyVaultNamespace.getFullName())
278-
.kmsProviders(kmsProviders)
279-
.build();
280-
281-
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
282-
283-
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
284-
285-
// Explicitly encrypt a field
286-
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
287-
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
288-
289-
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
290-
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
291-
.subscribe(insertOneSubscriber);
292-
insertOneSubscriber.await();
293-
294-
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
295-
collection.find().first().subscribe(documentSubscriber);
296-
297-
Document doc = documentSubscriber.get().get(0);
298-
System.out.println(doc.toJson());
299-
300-
// Explicitly decrypt the field
301-
System.out.println(
302-
clientEncryption.decrypt(new BsonBinary(doc.get("encryptedField", Binary.class).getData()))
303-
);
304-
305-
Explicit Encryption and Auto Decryption
306-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
307-
308-
Although automatic encryption requires MongoDB 4.2 enterprise or a
309-
MongoDB 4.2 Atlas cluster, automatic decryption is supported for all
310-
users. To configure automatic decryption without automatic encryption,
311-
set ``bypassAutoEncryption(true)``.
312-
313-
The code example is from the `ClientSideEncryptionExplicitEncryptionOnlyTour.java
314-
<{+driver-source-gh+}/blob/master/driver-reactive-streams/src/examples/reactivestreams/tour/ClientSideEncryptionExplicitEncryptionOnlyTour.java>`__
315-
file in the driver source code GitHub repository.
316-
317-
.. code-block:: java
318-
319-
...
320-
MongoClientSettings clientSettings = MongoClientSettings.builder()
321-
.autoEncryptionSettings(AutoEncryptionSettings.builder()
322-
.keyVaultNamespace(keyVaultNamespace.getFullName())
323-
.kmsProviders(kmsProviders)
324-
.bypassAutoEncryption(true)
325-
.build())
326-
.build();
327-
MongoClient mongoClient = MongoClients.create(clientSettings);
328-
329-
...
330-
331-
// Explicitly encrypt a field
332-
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
333-
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
334-
335-
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
336-
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
337-
.subscribe(insertOneSubscriber);
338-
insertOneSubscriber.await();
339-
340-
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
341-
collection.find().first().subscribe(documentSubscriber);
342-
343-
Document doc = documentSubscriber.get().get(0);
344-
System.out.println(doc.toJson());
3+
.. sharedinclude:: dbx/encrypt-fields.rst
4+
5+
.. replacement:: driver-specific-content
6+
7+
.. important:: Compatible Encryption Library Version
8+
9+
The {+driver-short+} uses the `mongodb-crypt
10+
<https://mvnrepository.com/artifact/org.mongodb/mongodb-crypt>`__
11+
encryption library for in-use encryption. This driver version
12+
is compatible with ``mongodb-crypt`` v{+full-version+}.
13+
14+
Select from the following :guilabel:`Maven` and
15+
:guilabel:`Gradle` tabs to see how to add the ``mongodb-crypt``
16+
dependency to your project by using the specified manager:
17+
18+
.. tabs::
19+
20+
.. tab:: Maven
21+
:tabid: maven-dependency
22+
23+
.. include:: /includes/security/crypt-maven-versioned.rst
24+
25+
.. tab:: Gradle
26+
:tabid: gradle-dependency
27+
28+
.. include:: source/includes/security/crypt-gradle-versioned.rst

source/whats-new.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ New features of the 5.2 driver release include:
4040
the `SearchIndexModel <{+api+}/mongodb-driver-core/com/mongodb/client/model/SearchIndexModel.html>`__
4141
API documentation
4242

43+
.. replacement:: encrypt-link
44+
45+
the :ref:`In-Use Encryption <javars-encrypt>` guide
46+
4347
.. replacement:: vector-search-link
4448

4549
the :atlas:`Atlas Vector Search Quick Start

0 commit comments

Comments
 (0)