Skip to content

Commit 865983f

Browse files
committed
PHPLIB-492: Create tutorial for client side encryption
1 parent 1ba76bf commit 865983f

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed

docs/tutorial.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Tutorials
1010
/tutorial/commands
1111
/tutorial/custom-types
1212
/tutorial/decimal128
13+
/tutorial/client-side-encryption
1314
/tutorial/gridfs
1415
/tutorial/indexes
1516
/tutorial/tailable-cursor
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
======================
2+
Client-Side Encryption
3+
======================
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
Client-Side Field Level Encryption allows administrators and developers to
14+
encrypt specific data fields in addition to other MongoDB encryption features.
15+
16+
17+
Automatic Encryption and Decryption
18+
-----------------------------------
19+
20+
.. note::
21+
22+
Auto encryption is an enterprise only feature.
23+
24+
The following example uses a local key, however using AWS Key Management Service
25+
is also an option. The data in the ``encryptedField`` field is automatically
26+
encrypted on insertion and decrypted when querying on the client side.
27+
28+
.. code-block:: php
29+
30+
<?php
31+
32+
use MongoDB\BSON\Binary;
33+
use MongoDB\Client;
34+
35+
$localKey = new Binary('<binary key data>', Binary::TYPE_GENERIC);
36+
37+
$encryptionOpts = [
38+
'keyVaultNamespace' => 'admin.datakeys',
39+
'kmsProviders' => [
40+
'local' => ['key' => $localKey],
41+
],
42+
];
43+
44+
$client = new Client('mongodb://127.0.0.1');
45+
$clientEncryption = $client->createClientEncryption($encryptionOpts);
46+
47+
$database = $client->selectDatabase('test');
48+
$database->dropCollection('coll'); // remove old data
49+
50+
// Create new key in the key vault and store its ID for later use
51+
$keyId = $clientEncryption->createDataKey('local');
52+
53+
$database->createCollection('coll', [
54+
'validator' => [
55+
'$jsonSchema' => [
56+
'bsonType' => 'object',
57+
'properties' => [
58+
'encryptedField' => [
59+
'encrypt' => [
60+
'keyId' => [$keyId],
61+
'bsonType' => 'string',
62+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
63+
],
64+
],
65+
],
66+
],
67+
],
68+
]);
69+
70+
$encryptedClient = new Client('mongodb://127.0.0.1', [], ['autoEncryption' => $encryptionOpts]);
71+
72+
$collection = $encryptedClient->selectCollection('test', 'coll');
73+
74+
$collection->insertOne(['encryptedField' => '123456789']);
75+
76+
var_dump($collection->findOne([]));
77+
78+
79+
Specifying an Explicit Schema for Encryption
80+
--------------------------------------------
81+
82+
The following example shows how to create a new key and store it in the key
83+
vault collection. The encrypted client configures an explicit schema for
84+
encryption using the newly created key.
85+
86+
.. note::
87+
88+
Supplying a ``schemaMap`` provides more security than relying on JSON schemas
89+
obtained from the server. It protects against a malicious server advertising
90+
a false JSON schema, which could trick the client into sending unencrypted
91+
data that should be encrypted.
92+
93+
.. code-block:: php
94+
95+
<?php
96+
97+
use MongoDB\BSON\Binary;
98+
use MongoDB\Client;
99+
use MongoDB\Driver\ClientEncryption;
100+
101+
$localKey = new Binary('<binary key data>', Binary::TYPE_GENERIC);
102+
103+
$clientEncryptionOpts = [
104+
'keyVaultNamespace' => 'admin.datakeys',
105+
'kmsProviders' => [
106+
'local' => ['key' => $localKey],
107+
],
108+
];
109+
110+
$client = new Client();
111+
$clientEncryption = $client->createClientEncryption($clientEncryptionOpts);
112+
113+
// Create new key in the key vault and store its ID for later use
114+
$keyId = $clientEncryption->createDataKey('local');
115+
116+
$autoEncryptionOpts = [
117+
'keyVaultNamespace' => 'admin.datakeys',
118+
'kmsProviders' => [
119+
'local' => ['key' => $localKey],
120+
],
121+
'schemaMap' => [
122+
'test.coll' => [
123+
'bsonType' => 'object',
124+
'properties' => [
125+
'encryptedField' => [
126+
'encrypt' => [
127+
'keyId' => [$keyId],
128+
'bsonType' => 'string',
129+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
130+
],
131+
],
132+
],
133+
],
134+
],
135+
];
136+
137+
$encryptedClient = new Client('mongodb://127.0.0.1', [], ['autoEncryption' => $autoEncryptionOpts]);
138+
139+
$collection = $encryptedClient->selectCollection('test', 'coll');
140+
$collection->drop(); // clear old data
141+
142+
$collection->insertOne(['encryptedField' => '123456789']);
143+
144+
var_dump($collection->findOne([]));
145+
146+
147+
Manually Encrypting and Decrypting Values
148+
-----------------------------------------
149+
150+
In the MongoDB Community Edition, you will have to manually encrypt and decrypt
151+
values before storing them in the database. The following example assumes that
152+
you have already created an encryption key in the key vault collection and
153+
explicitly encrypts and decrypts values in the document.
154+
155+
.. code-block:: php
156+
157+
<?php
158+
159+
use MongoDB\BSON\Binary;
160+
use MongoDB\Client;
161+
use MongoDB\Driver\ClientEncryption;
162+
163+
$localKey = new Binary('<binary key data>', Binary::TYPE_GENERIC);
164+
165+
$clientEncryptionOpts = [
166+
'keyVaultNamespace' => 'admin.datakeys',
167+
'kmsProviders' => [
168+
'local' => ['key' => $localKey],
169+
],
170+
];
171+
172+
$client = new Client();
173+
$clientEncryption = $client->createClientEncryption($clientEncryptionOpts);
174+
175+
// Create new key in the key vault and store its ID for later use
176+
$keyId = $clientEncryption->createDataKey('local');
177+
178+
$collection = $client->selectCollection('test', 'coll');
179+
$collection->drop(); // clear old data
180+
181+
$encryptionOpts = [
182+
'keyId' => $keyId,
183+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
184+
];
185+
$encryptedValue = $clientEncryption->encrypt('123456789', $encryptionOpts);
186+
187+
$collection->insertOne(['encryptedField' => $encryptedValue]);
188+
189+
$document = $collection->findOne();
190+
var_dump($clientEncryption->decrypt($document->encryptedField));

0 commit comments

Comments
 (0)