Skip to content

Commit 653de0e

Browse files
committed
Async Client side encryption support
And minor updates to the sync api so both apis mirror each other. JAVA-3312 JAVA-3359
1 parent abad65d commit 653de0e

File tree

56 files changed

+3549
-278
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3549
-278
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ docs/hugo*
4242

4343
# jenv
4444
.java-version
45+
46+
#mongocryptd
47+
**/mongocryptd.pid
48+

config/checkstyle-exclude.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<suppress checks="JavadocPackage" files="org[\\/]bson[\\/]types[\\/][^\\/]*\.java"/>
3838

3939
<suppress checks="Javadoc*" files="com[\\/]mongodb[\\/]internal[\\/]"/>
40+
<suppress checks="Javadoc*" files="com[\\/]mongodb[\\/]async[\\/]client[\\/]internal[\\/]"/>
4041
<suppress checks="Javadoc*" files="com[\\/]mongodb[\\/]client[\\/]internal[\\/]"/>
4142
<suppress checks="Javadoc*" files="org[\\/]bson[\\/]internal[\\/]"/>
4243

config/findbugs-exclude.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@
141141
<Bug pattern="NM_SAME_SIMPLE_NAME_AS_INTERFACE"/>
142142
</Match>
143143

144+
<Match>
145+
<Class name="~com.mongodb.async.client.internal.AsyncCryptConnection.*"/>
146+
<Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT"/>
147+
</Match>
148+
144149
<!-- Spotbugs assumes that SSLSocket#getSSLParameters never returns null, when that is not the case for all JDKs -->
145150
<Match>
146151
<Class name="com.mongodb.internal.connection.SocketStreamHelper"/>
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
+++
2+
date = "2019-06-13T09:00:01+01:00"
3+
title = "Client Side Encryption"
4+
[menu.main]
5+
parent = "Async Tutorials"
6+
identifier = "Async Client Side Encryption"
7+
weight = 16
8+
pre = "<i class='fa fa-lock'></i>"
9+
+++
10+
11+
# Client Side Encryption
12+
13+
New in MongoDB 4.2 client side encryption allows administrators and developers to encrypt specific data fields in addition to other
14+
MongoDB encryption features.
15+
16+
With field level encryption, developers can encrypt fields client side without any server-side
17+
configuration or directives. Client-side field level encryption supports workloads where applications must guarantee that
18+
unauthorized parties, including server administrators, cannot read the encrypted data.
19+
20+
{{% note class="important" %}}
21+
Java 8 is the minimum required version that supports Async client side encryption.
22+
{{% /note %}}
23+
24+
## Installation
25+
26+
The recommended way to get started using field level encryption in your project is with a dependency management system.
27+
Field level encryption requires additional packages to be installed as well as the driver itself.
28+
See the [installation]({{< relref "driver-async/getting-started/installation.md" >}}) for instructions on how to install the MongoDB driver.
29+
30+
{{< distroPicker >}}
31+
32+
### libmongocrypt
33+
34+
There is a separate jar file containing`libmongocrypt` bindings.
35+
36+
{{< install artifactId="mongodb-crypt" version="1.0.0-beta4">}}
37+
38+
### mongocryptd configuration
39+
40+
`libmongocrypt` requires the `mongocryptd` daemon / process to be running. A specific daemon / process uri can be configured in the
41+
`AutoEncryptionSettings` class by setting `mongocryptdURI` in the `extraOptions`.
42+
43+
More information about mongocryptd will soon be available from the official documentation.
44+
45+
46+
### Examples
47+
48+
The following is a sample app that assumes the **key** and **schema** have already been created in MongoDB. The example uses a local key,
49+
however using AWS Key Management Service is also an option. The data in the `encryptedField` field is automatically encrypted on the
50+
insert and decrypted when using find on the client side. The following code snippet comes from the
51+
[`ClientSideEncryptionSimpleTour.java`]({{< srcref "driver-async/src/driver-async/src/examples/tour/ClientSideEncryptionSimpleTour.java">}}) example code
52+
that can be found with the driver source on github:
53+
54+
```java
55+
import com.mongodb.AutoEncryptionSettings;
56+
import com.mongodb.MongoClientSettings;
57+
import com.mongodb.client.MongoClient;
58+
import com.mongodb.client.MongoClients;
59+
import com.mongodb.client.MongoCollection;
60+
import org.bson.Document;
61+
62+
import java.security.SecureRandom;
63+
import java.util.HashMap;
64+
import java.util.Map;
65+
import java.util.concurrent.CountDownLatch;
66+
67+
public class ClientSideEncryptionSimpleTour {
68+
69+
public static void main(final String[] args) {
70+
71+
// This would have to be the same master key as was used to create the encryption key
72+
final byte[] localMasterKey = new byte[96];
73+
new SecureRandom().nextBytes(localMasterKey);
74+
75+
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
76+
put("local", new HashMap<String, Object>() {{
77+
put("key", localMasterKey);
78+
}});
79+
}};
80+
81+
String keyVaultNamespace = "admin.datakeys";
82+
83+
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
84+
.keyVaultNamespace(keyVaultNamespace)
85+
.kmsProviders(kmsProviders)
86+
.build();
87+
88+
MongoClientSettings clientSettings = MongoClientSettings.builder()
89+
.autoEncryptionSettings(autoEncryptionSettings)
90+
.build();
91+
92+
MongoClient mongoClient = MongoClients.create(clientSettings);
93+
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
94+
final CountDownLatch dropLatch = new CountDownLatch(1);
95+
96+
// clear old data
97+
collection.drop(new SingleResultCallback<Void>() {
98+
@Override
99+
public void onResult(final Void result, final Throwable t) {
100+
dropLatch.countDown();
101+
}
102+
});
103+
dropLatch.await();
104+
105+
final CountDownLatch insertLatch = new CountDownLatch(1);
106+
collection.insertOne(new Document("encryptedField", "123456789"),
107+
new SingleResultCallback<Void>() {
108+
@Override
109+
public void onResult(final Void result, final Throwable t) {
110+
System.out.println("Inserted!");
111+
insertLatch.countDown();
112+
}
113+
});
114+
insertLatch.await();
115+
116+
final CountDownLatch findLatch = new CountDownLatch(1);
117+
collection.find().first(new SingleResultCallback<Document>() {
118+
@Override
119+
public void onResult(final Document result, final Throwable t) {
120+
System.out.println(result.toJson());
121+
findLatch.countDown();
122+
}
123+
});
124+
findLatch.await();
125+
}
126+
}
127+
```
128+
129+
{{% note %}}
130+
Auto encryption is an **enterprise** only feature.
131+
{{% /note %}}
132+
133+
The following example shows how to configure the `AutoEncryptionSettings` instance to create a new key and setting the json schema map.
134+
The full code snippet can be found in
135+
[`ClientSideEncryptionAutoEncryptionSettingsTour.java`]({{< srcref "driver-async/src/examples/tour/ClientSideEncryptionAutoEncryptionSettingsTour.java">}}):
136+
137+
```java
138+
import com.mongodb.ClientEncryptionSettings;
139+
import com.mongodb.ConnectionString;
140+
import com.mongodb.client.model.vault.DataKeyOptions;
141+
import com.mongodb.client.vault.ClientEncryption;
142+
import com.mongodb.client.vault.ClientEncryptions;
143+
import org.bson.BsonBinary;
144+
import org.bson.BsonDocument;
145+
146+
import java.util.Base64;
147+
148+
...
149+
150+
String keyVaultNamespace = "admin.datakeys";
151+
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
152+
.keyVaultMongoClientSettings(MongoClientSettings.builder()
153+
.applyConnectionString(new ConnectionString("mongodb://localhost"))
154+
.build())
155+
.keyVaultNamespace(keyVaultNamespace)
156+
.kmsProviders(kmsProviders)
157+
.build();
158+
159+
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
160+
161+
final CountDownLatch createKeyLatch = new CountDownLatch(1);
162+
final AtomicReference<String> base64DataKeyId = new AtomicReference<String>();
163+
clientEncryption.createDataKey("local", new DataKeyOptions(), new SingleResultCallback<BsonBinary>() {
164+
@Override
165+
public void onResult(final BsonBinary dataKeyId, final Throwable t) {
166+
base64DataKeyId.set(Base64.getEncoder().encodeToString(dataKeyId.getData()));
167+
createKeyLatch.countDown();
168+
}
169+
});
170+
createKeyLatch.await();
171+
172+
final String dbName = "test";
173+
final String collName = "coll";
174+
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
175+
.keyVaultNamespace(keyVaultNamespace)
176+
.kmsProviders(kmsProviders)
177+
.schemaMap(new HashMap<String, BsonDocument>() {{
178+
put(dbName + "." + collName,
179+
// Need a schema that references the new data key
180+
BsonDocument.parse("{"
181+
+ " properties: {"
182+
+ " encryptedField: {"
183+
+ " encrypt: {"
184+
+ " keyId: [{"
185+
+ " \"$binary\": {"
186+
+ " \"base64\": \"" + base64DataKeyId + "\","
187+
+ " \"subType\": \"04\""
188+
+ " }"
189+
+ " }],"
190+
+ " bsonType: \"string\","
191+
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\""
192+
+ " }"
193+
+ " }"
194+
+ " },"
195+
+ " \"bsonType\": \"object\""
196+
+ "}"));
197+
}}).build();
198+
```
199+
200+
**Coming soon:** An example using the community version and demonstrating explicit encryption/decryption.

docs/reference/content/driver/tutorials/client-side-encryption.md

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,19 @@ See the [installation]({{< relref "driver/getting-started/installation.md" >}})
2929

3030
There is a separate jar file containing`libmongocrypt` bindings.
3131

32-
{{< install artifactId="mongodb-crypt" version="1.0.0-beta2">}}
33-
34-
If the jar fails to run there are separate jar files for specific architectures:
35-
36-
#### RHEL 7.0*
37-
{{< install artifactId="mongodb-crypt" version="1.0.0-beta2" classifier="linux64-rhel70">}}
38-
39-
#### OSX*
40-
{{< install artifactId="mongodb-crypt" version="1.0.0-beta2" classifier="osx">}}
41-
42-
#### Windows*
43-
{{< install artifactId="mongodb-crypt" version="1.0.0-beta2" classifier="win64">}}
44-
45-
#### Ubuntu 16.04
46-
{{< install artifactId="mongodb-crypt" version="1.0.0-beta2" classifier="linux64-ubuntu1604">}}
47-
48-
49-
* Distribution is included in the main `mongodb-crypt` jar file.
32+
{{< install artifactId="mongodb-crypt" version="1.0.0-beta4">}}
5033

5134
### mongocryptd configuration
5235

5336
`libmongocrypt` requires the `mongocryptd` daemon / process to be running. A specific daemon / process uri can be configured in the
5437
`AutoEncryptionSettings` class by setting `mongocryptdURI` in the `extraOptions`.
5538

56-
More information about libmongocrypt will soon be available from the official documentation.
39+
More information about mongocryptd will soon be available from the official documentation.
5740

5841

5942
### Examples
6043

61-
The following is a sample app that assumes key and schema have already been created in MongoDB. The example uses a local key,
44+
The following is a sample app that assumes the **key** and **schema** have already been created in MongoDB. The example uses a local key,
6245
however using AWS Key Management Service is also an option. The data in the `encryptedField` field is automatically encrypted on the
6346
insert and decrypted when using find on the client side. The following code snippet comes from the
6447
[`ClientSideEncryptionSimpleTour.java`]({{< srcref "driver-sync/src/examples/tour/ClientSideEncryptionSimpleTour.java">}}) example code
@@ -174,8 +157,4 @@ AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
174157
}}).build();
175158
```
176159

177-
{{% note %}}
178-
Auto encryption is an **enterprise** only feature.
179-
{{% /note %}}
180-
181160
**Coming soon:** An example using the community version and demonstrating explicit encryption/decryption.

0 commit comments

Comments
 (0)