Set Up PureKit With Custom Storage

This guide shows how to set up a custom storage (for example, if you need a better perfomance) and initialize PureKit with it for storing users' encrypted password records, encryption keys and encrypted backup of password hashes.

Using Virgil Cloud makes integration process faster and simplifies PureKit management, because there is no need to change or add something into your database infrastructure. At the same time, this approach provides full transparency and security while using Virgil Storage. Also, Virgil Security is unable to decrypt encrypted private keys since they are protected with user password which is owned only by the user.

Before you begin

Modify storage

If you decide to use a custom storage, you'll need to add the following tables:

TableDescription
virgil_usersStores user password records (passwords encrypted with PHE protocol).
virgil_keysStores all the PureKit keys.
virgil_rolesStores user roles that you will need to share encrypted data for.
virgil_role_assignmentsLinks users and their assigned roles.
virgil_grant_keysStores users' EncryptedGrants, that are created during the authentication, used for decrypting data, and have an expiration date.

Here is an SQL script that you can use to modify your database:

CREATE TABLE virgil_users (
    user_id CHAR(36) NOT NULL PRIMARY KEY,
    record_version INTEGER NOT NULL,
    protobuf VARBINARY(2048) NOT NULL,
    INDEX record_version_index(record_version),
    UNIQUE INDEX user_id_record_version_index(user_id, record_version)
);


CREATE TABLE virgil_keys (
    user_id CHAR(36) NOT NULL,
    data_id VARCHAR(128) NOT NULL,
    protobuf VARBINARY(32768) NOT NULL, /* Up to 125 recipients */
    PRIMARY KEY(user_id, data_id),
    FOREIGN KEY (user_id) REFERENCES virgil_users(user_id) ON DELETE CASCADE
);

CREATE TABLE virgil_roles (
    role_name VARCHAR(64) NOT NULL PRIMARY KEY,
    protobuf VARBINARY(256) NOT NULL
);

CREATE TABLE virgil_role_assignments (
    role_name VARCHAR(64) NOT NULL,
    user_id CHAR(36) NOT NULL,
    protobuf VARBINARY(1024) NOT NULL,
    PRIMARY KEY(role_name, user_id),
    INDEX user_id_index(user_id),
    FOREIGN KEY (user_id) REFERENCES virgil_users(user_id) ON DELETE CASCADE,
    FOREIGN KEY (role_name) REFERENCES virgil_roles(role_name) ON DELETE CASCADE
);

CREATE TABLE virgil_grant_keys (
    record_version INTEGER NOT NULL
    user_id CHAR(36) NOT NULL,
    key_id BINARY(64) NOT NULL,
    expiration_date BIGINT NOT NULL,
    protobuf VARBINARY(512) NOT NULL,
    PRIMARY KEY(user_id, key_id),
    FOREIGN KEY (user_id) REFERENCES virgil_users(user_id) ON DELETE CASCADE,
    INDEX expiration_date_index(expiration_date),
    INDEX record_version_index(record_version)
);

SET @@global.event_scheduler = 1;

CREATE EVENT delete_expired_grant_keys ON SCHEDULE EVERY 120 SECOND DO DELETE FROM virgil_grant_keys WHERE expiration_date < UNIX_TIMESTAMP();

The delete_expired_grant_keys event is used for regularly deleting the Grants that have expired and, therefore, finish user's active session. To get a new Grant, the user will have to go through the authentication process again.

Implement PureStorage interface

Within your storage class you'll need to implement PureStorage interface (it is also recommended to implement PureModelSerializerDependent interface as well):

public class CustomPureStorage implements PureStorage, PureModelSerializerDependent { ... }

Inside the class, override the inteface's methods.

For your convenience, we've created an integration with MariaDB, which you can check out as an example of PureKit usage with a custom storage. Take a look at this file to see how we implemented the PureStorage interface with MariaDB storage.

Generate PureKit credentials

Go through the Generate PureKit Credentials guide and save the credentials for further usage.

Install PureKit

Use your package manager to install PureKit at your backend.

The PureKit Kotlin/Java is provided as a package named purekit with group id named com.virgilsecurity. You can either use Gradle or Maven to add it to your project dependencies.

Maven Add jcenter repository:

<repositories>
    <repository>
        <id>jcenter</id>
        <name>jCenter</name>
        <url>http://jcenter.bintray.com</url>
    </repository>
</repositories>

and add purekit dependency:

<dependencies>
    <dependency>
        <groupId>com.virgilsecurity</groupId>
        <artifactId>purekit</artifactId>
        <version><latest-version></version>
    </dependency>
</dependencies>

Gradle

Add jcenter repository:

repositories {
    jcenter()
}

and add purekit dependency:

implementation 'com.virgilsecurity:purekit:<latest-version>'

The <latest-version> of the SDK can be found in the Maven Central Repository: https://mvnrepository.com/artifact/com.virgilsecurity/purekit

Initialize PureKit with custom storage

Use the previously generated credentials to configure PureKit:

CustomPureStorage customPureStorage = new CustomPureStorage("jdbc:custom://localhost/puretest?user=root&password=qwerty");

PureContext context = PureContext.createContext(
    "AT.znqRZcOdzybj62Rzer897pX2DZ9KZoYF",
    "NM.Qs0YFBS7Mr3Aaa9qn4OCVcNC1wvPCXfUpZNWFCPUOUI=",
    "BU.MCowBQYDK2VwAyEAKWSBAZbbekJ5Ns36jRcjEiut3rH4rpaCCVnRxcB+d/E=",
    "SK.1.ieSin9pO6Bx96+RJw/85fARl4fWdD9DfU/JQF+mbdqE=.hMnMH+oIg8eKZNxGq27LYQbzK4gDlvWvMLJh3jBCkRk=.ug2KqJdUl50kYx+/RKcACLCR4zAujSlK6vQMvDKst+w=",
    "PK.1.BO/YeE7oxlUad1TSpKb3DtudynpwB9miM/+1CsMkmf50qP/QUaYt7pXIxrsyLh38u08p6FFkCWedy/VhA//2MJY=.BPkoDhRO/01QmA8JIVcqxMQKrXfA4agTjBFEm42Lh5NIimcEFWUNWXZwq1Q962rxfkJd7kNZDpm0mlPLeHU+iyI=",
    customPureStorage,
    null);

Pure pure = new Pure(context);

Next step

Now that you have PureKit installed and configured, you can move on to encrypting users' passwords as a part of user authentication: