Skip to content

Commit

Permalink
PHPLIB-1176: Various improvements for In-Use Encryption tutorial
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
jmikola committed Jul 5, 2023
1 parent 4d21326 commit 29db0f8
Show file tree
Hide file tree
Showing 15 changed files with 1,083 additions and 381 deletions.
39 changes: 39 additions & 0 deletions docs/examples/create_data_key.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

/* Create a client with no encryption options. Additionally, create a
* ClientEncryption object to manage data keys. */
$client = new Client($uri);

$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key. This would
* typically be done during application deployment. To store the key ID for
* later use, you can use serialize() or var_export(). */
$client->selectCollection('encryption', '__keyVault')->drop();
$keyId = $clientEncryption->createDataKey('local');

print_r($keyId);

// Encrypt a value using the key that was just created
$encryptedValue = $clientEncryption->encrypt('mySecret', [
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
'keyId' => $keyId,
]);

print_r($encryptedValue);
72 changes: 72 additions & 0 deletions docs/examples/csfle-automatic_encryption-local_schema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

/* Create a client with no encryption options. Additionally, create a
* ClientEncryption object to manage data keys. */
$client = new Client($uri);

$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key. Alternatively,
* this key ID could be read from a configuration file. */
$client->selectCollection('encryption', '__keyVault')->drop();
$keyId = $clientEncryption->createDataKey('local');

/* Create a client with automatic encryption enabled. Specify a schemaMap option
* to enforce a local JSON schema. */
$encryptedClient = new Client($uri, [], [
'autoEncryption' => [
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => ['local' => ['key' => $localKey]],
'schemaMap' => [
'test.coll' => [
'bsonType' => 'object',
'properties' => [
'encryptedField' => [
'encrypt' => [
'keyId' => [$keyId],
'bsonType' => 'string',
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
],
],
],
],
],
],
]);

// Drop and create the collection.
$encryptedClient->selectDatabase('test')->dropCollection('coll');
$encryptedClient->selectDatabase('test')->createCollection('coll');
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

/* Using the encrypted client, insert and find a document. The encrypted field
* will be automatically encrypted and decrypted. */
$encryptedCollection->insertOne([
'_id' => 1,
'encryptedField' => 'mySecret',
]);

print_r($encryptedCollection->findOne(['_id' => 1]));

/* Using the client configured without encryption, find the same document and
* observe that the field is not automatically decrypted. Additionally, the JSON
* schema will prohibit inserting a document with an unencrypted field value. */
$unencryptedCollection = $client->selectCollection('test', 'coll');

print_r($unencryptedCollection->findOne(['_id' => 1]));
73 changes: 73 additions & 0 deletions docs/examples/csfle-automatic_encryption-server_side_schema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

/* Create a client with no encryption options. Additionally, create a
* ClientEncryption object to manage data keys. */
$client = new Client($uri);

$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key. Alternatively,
* this key ID could be read from a configuration file. */
$client->selectCollection('encryption', '__keyVault')->drop();
$keyId = $clientEncryption->createDataKey('local');

// Create a client with automatic encryption enabled
$encryptedClient = new Client($uri, [], [
'autoEncryption' => [
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => ['local' => ['key' => $localKey]],
],
]);

/* Drop and create the collection. Specify a validator option when creating the
* collection to enforce a server-side JSON schema. */
$validator = [
'$jsonSchema' => [
'bsonType' => 'object',
'properties' => [
'encryptedField' => [
'encrypt' => [
'keyId' => [$keyId],
'bsonType' => 'string',
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
],
],
],
],
];

$encryptedClient->selectDatabase('test')->dropCollection('coll');
$encryptedClient->selectDatabase('test')->createCollection('coll', ['validator' => $validator]);
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

/* Using the encrypted client, insert and find a document. The encrypted field
* will be automatically encrypted and decrypted. */
$encryptedCollection->insertOne([
'_id' => 1,
'encryptedField' => 'mySecret',
]);

print_r($encryptedCollection->findOne(['_id' => 1]));

/* Using the client configured without encryption, find the same document and
* observe that the field is not automatically decrypted. Additionally, the JSON
* schema will prohibit inserting a document with an unencrypted field value. */
$unencryptedCollection = $client->selectCollection('test', 'coll');

print_r($unencryptedCollection->findOne(['_id' => 1]));
48 changes: 48 additions & 0 deletions docs/examples/csfle-explicit_encryption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

/* Create a client with no encryption options. Additionally, create a
* ClientEncryption object to manage data keys. */
$client = new Client($uri);

$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key. Alternatively,
* this key ID could be read from a configuration file. */
$client->selectCollection('encryption', '__keyVault')->drop();
$keyId = $clientEncryption->createDataKey('local');

// Select and drop a collection to use for this example
$collection = $client->selectCollection('test', 'coll');
$collection->drop();

// Insert a document with a manually encrypted field
$encryptedValue = $clientEncryption->encrypt('mySecret', [
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
'keyId' => $keyId,
]);

$collection->insertOne(['encryptedField' => $encryptedValue]);

/* Query for the document. The field will not be automatically decrypted
* because the client was not configured with an autoEncryption driver option.
* Manually decrypt the field value using the ClientEncryption object. */
$document = $collection->findOne();

print_r($document->encryptedField);
print_r($clientEncryption->decrypt($document->encryptedField));
52 changes: 52 additions & 0 deletions docs/examples/csfle-explicit_encryption_automatic_decryption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

// Create a client with automatic encryption disabled
$client = new Client($uri, [], [
'autoEncryption' => [
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => ['local' => ['key' => $localKey]],
'bypassAutoEncryption' => true,
],
]);

// Create a ClientEncryption object to manage data keys
$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key. Alternatively,
* this key ID could be read from a configuration file. */
$client->selectCollection('encryption', '__keyVault')->drop();
$keyId = $clientEncryption->createDataKey('local');

// Select and drop a collection to use for this example
$collection = $client->selectCollection('test', 'coll');
$collection->drop();

// Insert a document with a manually encrypted field
$encryptedValue = $clientEncryption->encrypt('mySecret', [
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
'keyId' => $keyId,
]);

$collection->insertOne(['encryptedField' => $encryptedValue]);

/* Query for the document. The field will still be automatically decrypted
* because the client was configured with an autoEncryption driver option. */
$document = $collection->findOne();

print_r($document->encryptedField);
37 changes: 37 additions & 0 deletions docs/examples/key_alt_name.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

use MongoDB\BSON\Binary;
use MongoDB\Client;
use MongoDB\Driver\ClientEncryption;

require __DIR__ . '/../../vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/';

// Generate a secure local key to use for this script
$localKey = new Binary(random_bytes(96));

/* Create a client with no encryption options. Additionally, create a
* ClientEncryption object to manage data keys. */
$client = new Client($uri);

$clientEncryption = $client->createClientEncryption([
'keyVaultNamespace' => 'encryption.__keyVault',
'kmsProviders' => [
'local' => ['key' => $localKey],
],
]);

/* Drop the key vault collection and create an encryption key with an alternate
* name. This would typically be done during application deployment. To store
* the key ID for later use, you can use serialize() or var_export(). */
$client->selectCollection('encryption', '__keyVault')->drop();
$clientEncryption->createDataKey('local', ['keyAltNames' => ['myDataKey']]);

// Encrypt a value, using the "keyAltName" option instead of "keyId"
$encryptedValue = $clientEncryption->encrypt('mySecret', [
'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
'keyAltName' => 'myDataKey',
]);

print_r($encryptedValue);
Loading

0 comments on commit 29db0f8

Please sign in to comment.