Navigation

In-Use Encryption

Dependencies

To get started using in-use encryption in your project, the PHP driver (i.e. mongodb extension) will need to be compiled with libmongocrypt (enabled by default).

Additionally, either crypt_shared or mongocryptd are required in order to use automatic client-side encryption. Neither is required for explicit encryption.

crypt_shared

The Automatic Encryption Shared Library (crypt_shared) provides the same functionality as mongocryptd, but does not require you to spawn another process to perform automatic encryption.

By default, the PHP driver attempts to load crypt_shared from the system path(s) and uses it automatically if found. To load crypt_shared from another location, use the cryptSharedLibPath auto encryption driver option when constructing a client. If the driver cannot load crypt_shared it will attempt to fallback to using mongocryptd by default. The cryptSharedLibRequired option may be used to always require crypt_shared and fail if it cannot be loaded.

For detailed installation instructions see the MongoDB documentation for the Automatic Encryption Shared Library.

mongocryptd

The mongocryptd binary is an alternative requirement for automatic client-side encryption and is included as a component in the MongoDB Enterprise Server package. For detailed installation instructions see the MongoDB documentation on mongocryptd.

mongocryptd performs the following:

  • Parses the automatic encryption rules specified in the client configuration. If the schemaMap auto encryption driver option contains invalid syntax, mongocryptd returns an error.
  • Uses the specified automatic encryption rules to mark fields in read and write operations for encryption.
  • Rejects read/write operations that may return unexpected or incorrect results when applied to an encrypted field. For supported and unsupported operations, see Supported Operations for Automatic Encryption.

A client configured with auto encryption will automatically spawn the mongocryptd process from the application’s PATH. Applications can control the spawning behavior via various auto encryption driver options.

mongocryptd is only responsible for supporting automatic client-side encryption and does not itself perform any encryption or decryption.

Managing Encryption Keys

See also

Encryption Key Management in the MongoDB manual

Creating an Encryption Key

Note

The following examples use a local master key. While this is suitable for development, a production application should use a supported cloud provider (e.g. AWS KMS). The master key is used to encrypt locally stored data keys and thus it is very important that you keep this key secure.

To create an encryption key, create a MongoDB\Driver\ClientEncryption instance with encryption options and use the createDataKey() method. The method will return the key ID which can be used to reference the key later. You can also pass multiple alternate names for this key and reference the key by these names instead of the key ID.

Creating a new data encryption key would typically be done on initial deployment, but depending on your use case you may want to use more than one encryption key (e.g. user-specific encryption keys) or create them dynamically.

<?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
$client = new Client($uri);

/* Prepare the database for this script. Drop the key vault collection and
 * ensure it has a unique index for keyAltNames. This would typically be done
 * during application deployment. */
$client->selectCollection('encryption', '__keyVault')->drop();
$client->selectCollection('encryption', '__keyVault')->createIndex(['keyAltNames' => 1], [
    'unique' => true,
    'partialFilterExpression' => ['keyAltNames' => ['$exists' => true]],
]);

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

/* Create a data encryption key. To store the key ID for later use, you can use
 * serialize(), var_export(), etc. */
$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);

Referencing Encryption Keys by an Alternative Name

To reference keys in your application, you can use the keyAltName attribute specified when creating the key. The following example creates an encryption key with an alternative name, which could be done when deploying the application. The script then encrypts data by referencing the key by its alternative name using the keyAltName option instead of keyId.

Note

Prior to adding a new key alternate name, you must create a partial, unique index on the keyAltNames field. Client-Side Field Level Encryption depends on server-enforced uniqueness of key alternate names.

<?php

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

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
$client = new Client($uri);

/* Prepare the database for this script. Drop the key vault collection and
 * ensure it has a unique index for keyAltNames. This would typically be done
 * during application deployment. */
$client->selectCollection('encryption', '__keyVault')->drop();
$client->selectCollection('encryption', '__keyVault')->createIndex(['keyAltNames' => 1], [
    'unique' => true,
    'partialFilterExpression' => ['keyAltNames' => ['$exists' => true]],
]);

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

// Create a data encryption key with an alternate name
$clientEncryption->createDataKey('local', ['keyAltNames' => ['myDataKey']]);

/* Attempt to create a second key with the same name to demonstrate that the
 * unique index is enforced. */
try {
    $clientEncryption->createDataKey('local', ['keyAltNames' => ['myDataKey']]);
} catch (ServerException $e) {
    printf("Error creating key: %s\n", $e->getMessage());
}

// 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);

Client-Side Field Level Encryption

Introduced in MongoDB 4.2, Client-Side Field Level Encryption allows an application to encrypt specific data fields in addition to pre-existing MongoDB encryption features such as Encryption at Rest and TLS/SSL (Transport Encryption).

With field level encryption, applications can encrypt fields in documents prior to transmitting data over the wire to the server. Client-side field level encryption supports workloads where applications must guarantee that unauthorized parties, including server administrators, cannot read the encrypted data.

Automatic Client-Side Field Level Encryption

Note

Automatic client-side field level encryption requires MongoDB 4.2+ Enterprise or a MongoDB 4.2+ Atlas cluster.

Automatic client-side field level encryption is enabled by creating a client and specifying the autoEncryption driver option. The following examples demonstrate how to setup automatic client-side field level encryption and use a MongoDB\Driver\ClientEncryption object to create a new encryption key.

Server-Side Field Level Encryption Enforcement

The MongoDB 4.2+ server supports using schema validation to enforce encryption of specific fields in a collection. This schema validation will prevent an application from inserting unencrypted values for any fields marked with the “encrypt” schema keyword.

The following example sets up a collection with automatic encryption using a $jsonSchema validator and Encryption Schema syntax. Data in the encryptedField field is automatically encrypted on insertion and decrypted when reading on the client side.

<?php

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

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

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

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

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

// Create a client with no encryption options
$client = new Client($uri);

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

/* Create a data encryption key. Alternatively, this key ID could be read from a
 * configuration file. */
$keyId = $clientEncryption->createDataKey('local');

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

// Define a JSON schema for the encrypted collection
$schema = [
    'bsonType' => 'object',
    'properties' => [
        'encryptedField' => [
            'encrypt' => [
                'keyId' => [$keyId],
                'bsonType' => 'string',
                'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
            ],
        ],
    ],
];

/* Create a new collection for this script. Configure a server-side schema by
 * explicitly creating the collection with a "validator" option. */
$encryptedClient->selectDatabase('test')->createCollection('coll', ['validator' => ['$jsonSchema' => $schema]]);
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

/* Using the encrypted client, insert and find a document to demonstrate that
 * the encrypted field is 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. */
$unencryptedCollection = $client->selectCollection('test', 'coll');

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

/* Attempt to insert another document with an unencrypted field value to
 * demonstrate that the server-side schema is enforced. */
try {
    $unencryptedCollection->insertOne(['_id' => 2, 'encryptedField' => 'myOtherSecret']);
} catch (ServerException $e) {
    printf("Error inserting document: %s\n", $e->getMessage());
}

Providing Local Automatic Encryption Rules

The following example uses the schemaMap auto encryption driver option to define encrypted fields using a strict subset of the JSON schema syntax.

Using schemaMap in conjunction with a server-side schema provides more security than relying entirely on a schema obtained from the server. It protects against a malicious server advertising a false schema, which could trick the client into sending unencrypted data that should be encrypted.

Note

Only Encryption Schema syntax can be used with the schemaMap option. Do not specify document validation keywords in the automatic encryption rules. To define document validation rules, configure schema validation.

<?php

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

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

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

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

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

// Create a client with no encryption options
$client = new Client($uri);

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

/* Create a data encryption key. Alternatively, this key ID could be read from a
 * configuration file. */
$keyId = $clientEncryption->createDataKey('local');

/* Define a JSON schema for the encrypted collection. Since this only utilizes
 * encryption schema syntax, it can be used for both the server-side and local
 * schema. */
$schema = [
    'bsonType' => 'object',
    'properties' => [
        'encryptedField' => [
            'encrypt' => [
                'keyId' => [$keyId],
                'bsonType' => 'string',
                'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
            ],
        ],
    ],
];

/* Create another client with automatic encryption enabled. Configure a local
 * schema for the encrypted collection using the "schemaMap" option. */
$encryptedClient = new Client($uri, [], [
    'autoEncryption' => [
        'keyVaultNamespace' => 'encryption.__keyVault',
        'kmsProviders' => ['local' => ['key' => $localKey]],
        'schemaMap' => ['test.coll' => $schema],
    ],
]);

/* Create a new collection for this script. Configure a server-side schema by
 * explicitly creating the collection with a "validator" option.
 *
 * Note: without a server-side schema, another client could potentially insert
 * unencrypted data into the collection. Therefore, a local schema should always
 * be used in conjunction with a server-side schema. */
$encryptedClient->selectDatabase('test')->createCollection('coll', ['validator' => ['$jsonSchema' => $schema]]);
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

/* Using the encrypted client, insert and find a document to demonstrate that
 * the encrypted field is 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. */
$unencryptedCollection = $client->selectCollection('test', 'coll');

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

/* Attempt to insert another document with an unencrypted field value to
 * demonstrate that the server-side schema is enforced. */
try {
    $unencryptedCollection->insertOne(['_id' => 2, 'encryptedField' => 'myOtherSecret']);
} catch (ServerException $e) {
    printf("Error inserting document: %s\n", $e->getMessage());
}

Explicit Encryption

Explicit encryption is a MongoDB community feature and does not use crypt_shared or mongocryptd. Explicit encryption is provided by the MongoDB\Driver\ClientEncryption class.

<?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/';

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

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

// Create a client with no encryption options
$client = new Client($uri);

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

/* Create a data encryption key. Alternatively, this key ID could be read from a
 * configuration file. */
$keyId = $clientEncryption->createDataKey('local');

// 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 = $client->selectCollection('test', 'coll');
$collection->insertOne(['_id' => 1, 'encryptedField' => $encryptedValue]);

/* Using the client configured without encryption, find the document and observe
 * that the field is not automatically decrypted. */

/** @var object{encryptedField: Binary} $document */
$document = $collection->findOne();

print_r($document);

// Manually decrypt the field
printf("Decrypted: %s\n", $clientEncryption->decrypt($document->encryptedField));

Explicit Encryption with Automatic Decryption

Although automatic encryption requires MongoDB 4.2+ enterprise or a MongoDB 4.2+ Atlas cluster, automatic decryption is supported for all users. To configure automatic decryption without automatic encryption set the bypassAutoEncryption auto encryption driver option when constructing a client.

<?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/';

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

// 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 encryption keys
$clientEncryption = $client->createClientEncryption([
    'keyVaultNamespace' => 'encryption.__keyVault',
    'kmsProviders' => [
        'local' => ['key' => $localKey],
    ],
]);

/* Create a data encryption key. Alternatively, this key ID could be read from a
 * configuration file. */
$keyId = $clientEncryption->createDataKey('local');

// 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 = $client->selectCollection('test', 'coll');
$collection->insertOne(['_id' => 1, 'encryptedField' => $encryptedValue]);

/* Using the client configured with encryption (but not automatic encryption),
 * find the document and observe that the field is automatically decrypted. */
$document = $collection->findOne();

print_r($document);

Queryable Encryption

Introduced in MongoDB 7.0, Queryable Encryption is another form of in-use encryption. Data is encrypted client-side. Queryable Encryption supports indexed encrypted fields, which are further processed server-side.

Automatic Queryable Encryption

Note

Automatic queryable encryption requires MongoDB 7.0+ Enterprise or a MongoDB 7.0+ Atlas cluster.

Automatic encryption in Queryable Encryption utilizes crypt_shared or mongocryptd to automatically encrypt and decrypt data client-side. The data in the encryptedIndexed and encryptedUnindexed fields will be automatically encrypted on insertion and decrypted when querying on the client side. Additionally, it is possible to query on the encryptedIndexed field.

<?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/';

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

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

// Create a client with no encryption options
$client = new Client($uri);

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

/* Create the data encryption keys for this script. Alternatively, the key IDs
 * could be read from a configuration file. */
$keyId1 = $clientEncryption->createDataKey('local');
$keyId2 = $clientEncryption->createDataKey('local');

/* Create another client with automatic encryption enabled. Configure the
 * encrypted collection using the "encryptedFields" option. */
$encryptedClient = new Client($uri, [], [
    'autoEncryption' => [
        'keyVaultNamespace' => 'encryption.__keyVault',
        'kmsProviders' => ['local' => ['key' => $localKey]],
        'encryptedFieldsMap' => [
            'test.coll' => [
                'fields' => [
                    [
                        'path' => 'encryptedIndexed',
                        'bsonType' => 'string',
                        'keyId' => $keyId1,
                        'queries' => ['queryType' => ClientEncryption::QUERY_TYPE_EQUALITY],
                    ],
                    [
                        'path' => 'encryptedUnindexed',
                        'bsonType' => 'string',
                        'keyId' => $keyId2,
                    ],
                ],
            ],
        ],
    ],
]);

/* Create the data collection for this script. The create and drop helpers will
 * infer encryptedFields from the client configuration and manage internal
 * encryption collections automatically. Alternatively, the "encryptedFields"
 * option can also be passed explicitly. */
$encryptedClient->selectDatabase('test')->createCollection('coll');
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

/* Using the encrypted client, insert a document and find it by querying on the
 * encrypted field. Fields will be automatically encrypted and decrypted. */
$encryptedCollection->insertOne([
    '_id' => 1,
    'encryptedIndexed' => 'indexedValue',
    'encryptedUnindexed' => 'unindexedValue',
]);

print_r($encryptedCollection->findOne(['encryptedIndexed' => 'indexedValue']));

/* Using the client configured without encryption, find the same document and
 * observe that fields are not automatically decrypted. */
$unencryptedCollection = $client->selectCollection('test', 'coll');

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

Explicit Queryable Encryption

Note

Explicit queryable encryption requires MongoDB 7.0+.

Explicit encryption in Queryable Encryption is performed using the MongoDBDriverClientEncryption::encrypt() and decrypt() methods. Although values must be explicitly encrypted (e.g. insertions, query criteria), automatic decryption for queries is possible by configuring encryptedFields on the collection, as demonstrated in the following example:

<?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/';

/* Note: this script assumes that the test database is empty and that the key
 * vault collection exists and has a partial, unique index on keyAltNames (as
 * demonstrated in the encryption key management scripts). */

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

// Create a client with no encryption options
$client = new Client($uri);

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

/* Create the data encryption keys. Alternatively, the key IDs could be read
 * from a configuration file. */
$keyId1 = $clientEncryption->createDataKey('local');
$keyId2 = $clientEncryption->createDataKey('local');

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

// Define encrypted fields for the collection
$encryptedFields = [
    'fields' => [
        [
            'path' => 'encryptedIndexed',
            'bsonType' => 'string',
            'keyId' => $keyId1,
            'queries' => ['queryType' => ClientEncryption::QUERY_TYPE_EQUALITY],
        ],
        [
            'path' => 'encryptedUnindexed',
            'bsonType' => 'string',
            'keyId' => $keyId2,
        ],
    ],
];

/* Create the data collection for this script. Specify the "encryptedFields"
 * option to ensure that internal encryption collections are also created. The
 * "encryptedFields" option should also be specified when dropping the
 * collection to ensure that internal encryption collections are dropped. */
$encryptedClient->selectDatabase('test')->createCollection('coll', ['encryptedFields' => $encryptedFields]);
$encryptedCollection = $encryptedClient->selectCollection('test', 'coll');

// Insert a document with manually encrypted fields
$indexedInsertPayload = $clientEncryption->encrypt('indexedValue', [
    'algorithm' => ClientEncryption::ALGORITHM_INDEXED,
    'contentionFactor' => 1,
    'keyId' => $keyId1,
]);

$unindexedInsertPayload = $clientEncryption->encrypt('unindexedValue', [
    'algorithm' => ClientEncryption::ALGORITHM_UNINDEXED,
    'keyId' => $keyId2,
]);

$encryptedCollection->insertOne([
    '_id' => 1,
    'encryptedIndexed' => $indexedInsertPayload,
    'encryptedUnindexed' => $unindexedInsertPayload,
]);

/* Encrypt the payload for an "equality" query using the same key that was used
 * to encrypt the corresponding insert payload. */
$indexedFindPayload = $clientEncryption->encrypt('indexedValue', [
    'algorithm' => ClientEncryption::ALGORITHM_INDEXED,
    'queryType' => ClientEncryption::QUERY_TYPE_EQUALITY,
    'contentionFactor' => 1,
    'keyId' => $keyId1,
]);

/* Using the client configured with encryption (but not automatic encryption),
 * find the document and observe that the fields are automatically decrypted. */
print_r($encryptedCollection->findOne(['encryptedIndexed' => $indexedFindPayload]));
←   Decimal128 GridFS  →