Data Encryption

This guide shows how to encrypt and decrypt data with PureKit.

Not only user passwords are sensitive data. In this flow we will help you protect any Personally identifiable information (PII) in your database.

PII is data that could potentially identify a specific individual, and PII is sensitive. Sensitive PII is information, when disclosed, could result in harm to the individual whose privacy has been breached. Sensitive PII should therefore be encrypted in transit and when data is at rest. Such information includes biometric information, medical information, personally identifiable financial information (PIFI), and unique identifiers such as passport or Social Security numbers.

How encryption works with PHE

The PHE service allows you to protect user's PII (personal data) with a user's encryptionKey that is obtained from the enrollAccount or verifyPassword functions (see the Verify User's Password section). The encryptionKey will be the same for both functions.

In addition, this key is unique to a particular user and won't be changed even after rotating (updating) a user's Pure Record. The encryptionKey will be updated after a user changes their own password.

Virgil Security has zero knowledge about a user's encryptionKey, because the key is calculated every time you execute the enrollAccount or verifyPassword functions on your server side.

Encryption is performed using AES256-GCM with key & nonce derived from the user's encryptionKey using HKDF and the random 256-bit salt.


Data encryption & decryption

Here is an example of data encryption/decryption with an encryptionKey:

using Virgil.PureKit; using Virgil.PureKit.Phe; using Virgil.PureKit.Utils; var phe = new PheCrypto(); var data = Bytes.FromString("Personal data", StringEncoding.UTF8); //verifyResult.Key is obtained from protocol.EnrollAccountAsync() // or protocol.VerifyPasswordAsync() calls var ciphertext = phe.Encrypt(data, verifyResult.Key); var decrypted = phe.Decrypt(ciphertext, verifyResult.Key); //use decrypted data

Re-encrypt data when password is changed

Use this flow when a user wants to change their password and maintain access to their data.

When Pure Record for the user is created for the very first time, generate a new key (let's call it User Key) and store it in your database.

Prepare database

Create a new column in your database for storing User Keys.

ParametersTypeSize (bytes)Description
Ecnrypted User Keybytearray210A unique key for user's data encryption.

Obtain Pure Record key

When the Pure Record is created for the very first time, you need to obtain the encryptionKey from the enrollAccount function (see the Generate User's Pure Record section).

Generate User Key

To generate a User Key, install Virgil Crypto Library and use the code snippet below. Store the public key in your database and save the private key securely on another external device.

Encrypt and store User Key

Encrypt the User Key with the encryptionKey and save the Encrypted User Key at your database.

Encrypt data with User Key

Whenever the user needs to encrypt their data, decrypt the Encrypted User Key with the encryptionKey and use the decrypted User Key instead of the encryptionKey for encrypting user's data.

Change user's password

To change the password, user enters their old password to authenticate at backend, and the new password. Use their new password to create a new Pure Record for the user.

During the password change, decrypt the Encrypted User Key with the old encryptionKey and encrypt the User Key with the new encryptionKey you get from enrollAccount using the new password. This will allow the user to access their data without re-encrypting all of it.

After that, you can delete the old Pure Record from your database and save the new one instead.