Repository navigation
Property Encryption #1471
MaxAake
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Property Encryption allows Neo4j properties to be encrypted and decrypted on the driver side.
Property values are encrypted and encoded into bytes. The resulting bytes contain the encrypted value together with the
metadata required to decrypt it. The application is responsible for storing these bytes in a representation supported by
Neo4j property types. To decrypt a value, the application retrieves the stored bytes and provides them to the driver.
The feature is designed to be easy to use, with an opinionated approach to encryption and decryption. All official Neo4j
drivers are expected to support the feature, enabling interoperability between drivers when they are configured to use
compatible encryption settings.
Important
Preview Feature
The preview feature is a new feature that is a candidate for a future GA status.
It enables users to try the feature out and maintainers to refine and update it.
The preview features are not considered to be experimental, temporary or unstable.
However, they may change more rapidly, without following the usual deprecation cycle.
Most preview features are expected to be granted the GA status unless some unexpected conditions arise.
Note
This feature is available from version 6.3.0 onwards.
Note
At present, all encryption and decryption is manual. As an official Neo4j Driver feature, Property Encryption enables:
While Property Encryption API includes a more detailed overview, the following two examples demonstrate the basic usage of the API.
Encryption example:
Decryption example:
Supported types
Property Encryption supports encrypting Neo4j Database Property types, namely:
stored in lists), although lists in general cannot be stored as properties. Lists stored as properties cannot contain
null values.
Encryption profile
An encryption profile defines the settings and operating mode used by the driver when encrypting and decrypting values.
Each profile has a unique, user-defined name. The profile name is stored with encrypted values and allows drivers to
identify which profile must be used to decrypt a value.
Multiple profiles can be configured at the same time, providing each has a unique name.
Note
When driver interoperability is required, users are expected to configure each driver with compatible profiles.
EncryptionProfileis the base type for encryption profiles. At present, the driver provides one profile type:EnvelopeEncryptionProfile. Additional profile types may be introduced in the future.Profiles are configured at the driver level using a driver configuration option:
Key Encapsulation Service
Key Encapsulation Service is responsible for generating, encapsulating, and decapsulating data encryption keys. It
generates a new data encryption key together with its encapsulation, and can later decapsulate the encapsulation to
recover the data encryption key when it is needed for encryption or decryption.
The key encapsulation mechanism is implementation-specific. It may use key wrapping, symmetric or asymmetric
cryptography, a key management service (KMS), or a post-quantum key encapsulation mechanism such as ML-KEM.
The service is represented by
KeyEncapsulationServiceinterface that has 2 primary methods:Local
The local implementation uses a user-provided AES-256 key in the form of a 32-length
Uint8Arrayas a master key for encapsulating and decapsulating data encryption keys.The encapsulation uses AES-GCM (
"AES/GCM/NoPadding") with the provided master key. The resulting encapsulationcontains a 256-bit AES data encryption key protected by the master key, together with a 96-bit (12-byte) initialization
vector (IV) and a 128-bit (16-byte) authentication tag.
Cloud KMS Providers
Implementations for Google, AWS, and Azure KMS providers will be made available in separate NPM packages following release of the driver implementation
Encapsulated Key Record Repository
An Encapsulated Key Record Repository is a user-provided repository for storing encapsulated data keys and their
associated metadata.
Each encapsulated key record has a globally unique and immutable identifier.
Important
The repository implementation is responsible for assigning globally unique and immutable key identifiers.
In addition, the repository is also responsible for enforcing alias uniqueness.
The repository is represented by
EncapsulatedKeyRecordRepositoryinterface that has 5 primary methods:create- creates a new key recordfindById- finds key by idfindByAlias- finds key by aliassetAliasById- sets key alias by iddeleteById- deletes key by idProperty Encryption API
The Property Encryption API is exposed through the
encryptionproperty on the Driverobject. This makes the API easy to access, particularly in existing applications where the driver object is already
available.
keyManager
The Envelope Profile requires data keys to exist before they can be used to encrypt or decrypt property values.
Creating a data key involves obtaining a new data encryption key and its encapsulation from the
Key Encapsulation Service and creating the corresponding record in the Encapsulated Key Record Repository.
Obtain key manager:
Note
A data key can be referenced by its globally unique identifier or, if assigned, by an alias. Both are String values.
The key identifier is immutable and globally unique, assigned by the key repository. The alias is a mutable,
application-level reference that can be reassigned to a different key over time.
Aliases allow applications to refer to keys using stable application-level names without having to reference the key's
identifier.
The key manager provides operations to create, find, and delete keys. It also provides operations to set and delete key
aliases. When Caching is enabled, key management operations update the Key Cache and Key Alias Index as necessary.
Create a data key with an alias:
Find key by alias:
Set alias by id:
Delete alias by id:
Delete key by id:
encrypt
Property values can be encrypted using the asynchronous
encryptfunction, which takes a parameter object.Encrypt value:
valueshould be the value to be encrypted.keyOptionsshould be an object with a fieldaliasorid, which is the key to be used when encrypting. It can alternatively be a string, which will be interpreted as the id of the key.encryptionProfileshould be a string, which is the name of the profile to be used. If the driver is configured with only one profile this field can be omitted, and the sole profile will be used. If there are multiple profiles, it must be provided.aadshould be an associated value to use for additional authentication, details are below.The returned value will be an
Int8Array, which will be stored as a byte blob in the server if sent as a query parameter.Important
The encrypted value always references the encryption key identifier, which is expected to be immutable and globally
unique. This ensures that the identifier used by the encrypted value is stable, even when a key alias is used in the
encryption request.
Additional Authenticated Data (AAD) is optional, non-secret data that is authenticated together with the encrypted
value but is not itself encrypted. The same AAD must be provided during decryption. Otherwise, decryption fails.
Important
It is recommended to use AAD to bind an encrypted value to application-specific context where possible, such as a user
identifier. This ensures that the context is authenticated when the value is later decrypted.
AAD should not contain confidential information.
Only the following Neo4j property types are supported as AAD:
NFCbefore providing them to the driver when bothencrypting and decrypting values
decrypt
The decrypting function
decryptfunctions similarly toencryptDecrypt value:
ciphertextshould be aInt8Arrayproduced by a driver's encryption function.usePersistedAadis optional, and should be a boolean if set, if set to true the decryption will use the stored AAD value, effectively skipping the extra validation that AAD provides.aadis optional, and should be the AAD value used in encryption if set.If AAD was set in encryption, then either
usePersistedAadmust be true oraadmust be set, else decryption will fail. Both should not be set at once.Important
It is recommended to provide AAD externally when possible, especially when the encrypted value was bound to
application-specific context during encryption. The externally provided AAD must match the AAD used during encryption.
Caching
The Envelope Profile supports 2 related caches:
Note
Each profile instance maintains its own dedicated caches.
Key Cache
The driver caches decapsulated data encryption keys by default to avoid repeatedly resolving and decapsulating the same
key.
Depending on the Envelope Profile and Encapsulated Key Record Repository implementations, resolving a
key may require network exchanges. Caching can therefore reduce the number of repeated key resolution operations.
The key cache is keyed by the key's globally unique identifier and has a configurable maximum size and time-to-live
(TTL). The default size is
100and TTL is15minutes.The key cache can be configured when creating an Envelope Profile:
Configure Key Cache:
The key cache is bounded and uses a least-recently-used (LRU) eviction policy when its configured maximum size is
reached. Entries that have exceeded their configured TTL are treated as cache misses and are not used.
The key cache can also be disabled by setting it's max size to 0
Key Alias Index
Aliases are resolved through a key alias index that maps aliases to key identifiers. The alias index does not contain
key material.
The alias index has its own configurable maximum size and TTL. The default size is
100and TTL is15seconds.Note
This allows alias mappings to expire independently of cached keys and limits the period for which a driver may use a
stale alias after it has been reassigned.
The alias index can be configured when creating an Envelope Profile:
Customize Key Alias Index:
Like the key cache, the alias index is bounded and uses a least-recently-used (LRU) eviction policy when its configured
maximum size is reached. Entries that have exceeded their configured TTL are treated as cache misses and are not used.
The key alias index is disabled when the key cache is disabled. It can also be disabled independently by setting index max size to 0:
FIPS compliant cryptography provider in Node
Encryption is performed using the WebCrypto API, when using node this API is called through the Node crypto implementation.
If you wish to ensure that the cryptographic provider used by the driver is FIPS compliant, you will need to ensure your JS runtime is correctly configured to use these providers. For node, this means following the [Node Crypto Fips Mode Guide)[https://nodejs.org/api/crypto.html#fips-mode].
All reactions