Skip to content

Commit f2328c3

Browse files
committed
PHPLIB-1176: Various improvements for In-Use Encryption tutorial
Adds additional non-enterprise examples from the PyMongo tutorial: "Explicit Encryption with Automatic Decryption" and "Explicit Queryable Encryption". Examples are now broken out into separate files, which are tested in ExamplesTest. Renames "Client-Side Encryption" to "In-Use Encryption" (PHPLIB-997). This will warrant adding a redirect from "/tutorial/client-side-encryption/" to "/tutorial/encryption/" in the related docs-php-library project. Adds docs for crypt_shared and mongocryptd (PHPLIB-985).
1 parent 4d21326 commit f2328c3

15 files changed

+1056
-378
lines changed

docs/examples/create_data_key.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
/* Create a client with no encryption options. Additionally, create a
15+
* ClientEncryption object to manage data keys. */
16+
$client = new Client($uri);
17+
18+
$clientEncryption = $client->createClientEncryption([
19+
'keyVaultNamespace' => 'encryption.__keyVault',
20+
'kmsProviders' => [
21+
'local' => ['key' => $localKey],
22+
],
23+
]);
24+
25+
/* Drop the key vault collection and create an encryption key. This would
26+
* typically be done during application deployment. To store the key ID for
27+
* later use, you can use serialize() or var_export(). */
28+
$client->selectCollection('encryption', '__keyVault')->drop();
29+
$keyId = $clientEncryption->createDataKey('local');
30+
31+
print_r($keyId);
32+
33+
// Encrypt a value using the key that was just created
34+
$encryptedValue = $clientEncryption->encrypt('mySecret', [
35+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
36+
'keyId' => $keyId,
37+
]);
38+
39+
print_r($encryptedValue);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
/* Create a client with no encryption options. Additionally, create a
15+
* ClientEncryption object to manage data keys. */
16+
$client = new Client($uri);
17+
18+
$clientEncryption = $client->createClientEncryption([
19+
'keyVaultNamespace' => 'encryption.__keyVault',
20+
'kmsProviders' => [
21+
'local' => ['key' => $localKey],
22+
],
23+
]);
24+
25+
/* Drop the key vault collection and create an encryption key. Alternatively,
26+
* this key ID could be read from a configuration file. */
27+
$client->selectCollection('encryption', '__keyVault')->drop();
28+
$keyId = $clientEncryption->createDataKey('local');
29+
30+
/* Create a client with automatic encryption enabled. Specify a schemaMap option
31+
* to enforce a local JSON schema. */
32+
$encryptedClient = new Client($uri, [], [
33+
'autoEncryption' => [
34+
'keyVaultNamespace' => 'encryption.__keyVault',
35+
'kmsProviders' => ['local' => ['key' => $localKey]],
36+
'schemaMap' => [
37+
'test.coll' => [
38+
'bsonType' => 'object',
39+
'properties' => [
40+
'encryptedField' => [
41+
'encrypt' => [
42+
'keyId' => [$keyId],
43+
'bsonType' => 'string',
44+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
45+
],
46+
],
47+
],
48+
],
49+
],
50+
],
51+
]);
52+
53+
// Drop and create the collection.
54+
$encryptedClient->selectDatabase('test')->dropCollection('coll');
55+
$encryptedClient->selectDatabase('test')->createCollection('coll');
56+
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');
57+
58+
/* Using the encrypted client, insert and find a document. The encrypted field
59+
* will be automatically encrypted and decrypted. */
60+
$encryptedCollection->insertOne([
61+
'_id' => 1,
62+
'encryptedField' => 'mySecret',
63+
]);
64+
65+
print_r($encryptedCollection->findOne(['_id' => 1]));
66+
67+
/* Using the client configured without encryption, find the same document and
68+
* observe that the field is not automatically decrypted. Additionally, the JSON
69+
* schema will prohibit inserting a document with an unencrypted field value. */
70+
$unencryptedCollection = $client->selectCollection('test', 'coll');
71+
72+
print_r($unencryptedCollection->findOne(['_id' => 1]));
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
/* Create a client with no encryption options. Additionally, create a
15+
* ClientEncryption object to manage data keys. */
16+
$client = new Client($uri);
17+
18+
$clientEncryption = $client->createClientEncryption([
19+
'keyVaultNamespace' => 'encryption.__keyVault',
20+
'kmsProviders' => [
21+
'local' => ['key' => $localKey],
22+
],
23+
]);
24+
25+
/* Drop the key vault collection and create an encryption key. Alternatively,
26+
* this key ID could be read from a configuration file. */
27+
$client->selectCollection('encryption', '__keyVault')->drop();
28+
$keyId = $clientEncryption->createDataKey('local');
29+
30+
// Create a client with automatic encryption enabled
31+
$encryptedClient = new Client($uri, [], [
32+
'autoEncryption' => [
33+
'keyVaultNamespace' => 'encryption.__keyVault',
34+
'kmsProviders' => ['local' => ['key' => $localKey]],
35+
],
36+
]);
37+
38+
/* Drop and create the collection. Specify a validator option when creating the
39+
* collection to enforce a server-side JSON schema. */
40+
$validator = [
41+
'$jsonSchema' => [
42+
'bsonType' => 'object',
43+
'properties' => [
44+
'encryptedField' => [
45+
'encrypt' => [
46+
'keyId' => [$keyId],
47+
'bsonType' => 'string',
48+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
49+
],
50+
],
51+
],
52+
],
53+
];
54+
55+
$encryptedClient->selectDatabase('test')->dropCollection('coll');
56+
$encryptedClient->selectDatabase('test')->createCollection('coll', ['validator' => $validator]);
57+
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');
58+
59+
/* Using the encrypted client, insert and find a document. The encrypted field
60+
* will be automatically encrypted and decrypted. */
61+
$encryptedCollection->insertOne([
62+
'_id' => 1,
63+
'encryptedField' => 'mySecret',
64+
]);
65+
66+
print_r($encryptedCollection->findOne(['_id' => 1]));
67+
68+
/* Using the client configured without encryption, find the same document and
69+
* observe that the field is not automatically decrypted. Additionally, the JSON
70+
* schema will prohibit inserting a document with an unencrypted field value. */
71+
$unencryptedCollection = $client->selectCollection('test', 'coll');
72+
73+
print_r($unencryptedCollection->findOne(['_id' => 1]));
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
/* Create a client with no encryption options. Additionally, create a
15+
* ClientEncryption object to manage data keys. */
16+
$client = new Client($uri);
17+
18+
$clientEncryption = $client->createClientEncryption([
19+
'keyVaultNamespace' => 'encryption.__keyVault',
20+
'kmsProviders' => [
21+
'local' => ['key' => $localKey],
22+
],
23+
]);
24+
25+
/* Drop the key vault collection and create an encryption key. Alternatively,
26+
* this key ID could be read from a configuration file. */
27+
$client->selectCollection('encryption', '__keyVault')->drop();
28+
$keyId = $clientEncryption->createDataKey('local');
29+
30+
// Select and drop a collection to use for this example
31+
$collection = $client->selectCollection('test', 'coll');
32+
$collection->drop();
33+
34+
// Insert a document with a manually encrypted field
35+
$encryptedValue = $clientEncryption->encrypt('mySecret', [
36+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
37+
'keyId' => $keyId,
38+
]);
39+
40+
$collection->insertOne(['encryptedField' => $encryptedValue]);
41+
42+
/* Query for the document. The field will not be automatically decrypted
43+
* because the client was not configured with an autoEncryption driver option.
44+
* Manually decrypt the field value using the ClientEncryption object. */
45+
$document = $collection->findOne();
46+
47+
print_r($document->encryptedField);
48+
print_r($clientEncryption->decrypt($document->encryptedField));
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
// Create a client with automatic encryption disabled
15+
$client = new Client($uri, [], [
16+
'autoEncryption' => [
17+
'keyVaultNamespace' => 'encryption.__keyVault',
18+
'kmsProviders' => ['local' => ['key' => $localKey]],
19+
'bypassAutoEncryption' => true,
20+
],
21+
]);
22+
23+
// Create a ClientEncryption object to manage data keys
24+
$clientEncryption = $client->createClientEncryption([
25+
'keyVaultNamespace' => 'encryption.__keyVault',
26+
'kmsProviders' => [
27+
'local' => ['key' => $localKey],
28+
],
29+
]);
30+
31+
/* Drop the key vault collection and create an encryption key. Alternatively,
32+
* this key ID could be read from a configuration file. */
33+
$client->selectCollection('encryption', '__keyVault')->drop();
34+
$keyId = $clientEncryption->createDataKey('local');
35+
36+
// Select and drop a collection to use for this example
37+
$collection = $client->selectCollection('test', 'coll');
38+
$collection->drop();
39+
40+
// Insert a document with a manually encrypted field
41+
$encryptedValue = $clientEncryption->encrypt('mySecret', [
42+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
43+
'keyId' => $keyId,
44+
]);
45+
46+
$collection->insertOne(['encryptedField' => $encryptedValue]);
47+
48+
/* Query for the document. The field will still be automatically decrypted
49+
* because the client was configured with an autoEncryption driver option. */
50+
$document = $collection->findOne();
51+
52+
print_r($document->encryptedField);

docs/examples/key_alt_name.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
use MongoDB\BSON\Binary;
4+
use MongoDB\Client;
5+
use MongoDB\Driver\ClientEncryption;
6+
7+
require __DIR__ . '/../../vendor/autoload.php';
8+
9+
$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';
10+
11+
// Generate a secure local key to use for this script
12+
$localKey = new Binary(random_bytes(96));
13+
14+
/* Create a client with no encryption options. Additionally, create a
15+
* ClientEncryption object to manage data keys. */
16+
$client = new Client($uri);
17+
18+
$clientEncryption = $client->createClientEncryption([
19+
'keyVaultNamespace' => 'encryption.__keyVault',
20+
'kmsProviders' => [
21+
'local' => ['key' => $localKey],
22+
],
23+
]);
24+
25+
/* Drop the key vault collection and create an encryption key with an alternate
26+
* name. This would typically be done during application deployment. To store
27+
* the key ID for later use, you can use serialize() or var_export(). */
28+
$client->selectCollection('encryption', '__keyVault')->drop();
29+
$clientEncryption->createDataKey('local', ['keyAltNames' => ['myDataKey']]);
30+
31+
// Encrypt a value, using the "keyAltName" option instead of "keyId"
32+
$encryptedValue = $clientEncryption->encrypt('mySecret', [
33+
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
34+
'keyAltName' => 'myDataKey',
35+
]);
36+
37+
print_r($encryptedValue);

0 commit comments

Comments
 (0)