# Quick-start

To get started quickly, we'll integrate the encryption & decryption features directly into the sample project, by password protecting the identity.

The branch on which this step is based is master (opens new window), the end result is 1-quick-start (opens new window).

# Installation

We will use the web version of the SDK @seald-io/sdk-web with the password identity protection module @seald-io/sdk-plugin-ssks-password:

cd frontend
npm install @seald-io/sdk-web @seald-io/sdk-plugin-ssks-password

For the moment, there are no changes to make to the backend.

# Configuration

To configure the SDK, you have to connect to your administration dashboard and get the following 3 elements:

  • appId: unique UUID for your application;
  • validationKeyId : unique UUID of the validation key;
  • validationKey : secret validation key corresponding to the validationKeyId used to generate offline license tokens.

TIP

To create a developer account, follow the first steps.

To instantiate the SDK, we proceed as follows:

TIP

Since the SDK instance is shared across an entire application in React, it is better to store it in a variable in a seald.js service file and expose a getter rather than storing it in an immutable variable.

# Seald identity Management

When creating a Seald identity, it must be associated to the Seald developer account, and to the user (whose identifier is noted userId) in the application in which the SDK is integrated.

To do this, we must generate a user license token called userLicenseToken from the validationKeyId, the validationKey and the userId and use it when creating the identity.

# Generating a userLicenseToken

The generation of a userLicenseToken is done offline, and is described in this dedicated guide.

This operation must be done from the backend, but first we will do it on the frontend side to get a working prototype faster. We can use the function utils.generateUserLicenseToken as follows:

WARNING

In production, you must not give the frontend knowledge of the validation key. If it were, it could be used by an attacker to create new accounts associated with your developer account, and in particular to use your quotas.

You can refer to the guide dedicated to validation tokens.

# Creating an identity

Once the token is generated, a new identity can be created as follows:

Once this function is executed, the SDK instance is ready to encrypt and decrypt, and the identity-specific keys are in memory.

# Password-protection of the identity

Once the identity is created, it exists only in memory, it must be saved to be used in a later session.

To do this we will use the @seald-io/sdk-plugin-ssks-password module which allows to protect the identity keys with a password.

Once this function is executed, the identity is saved and can be retrieved using the equivalent function sealdSDKInstance.ssksPassword.retrieveIdentity from a newly instantiated instance.

For more details on this mechanism, refer to the guide dedicated to password protection.

# Exposing a createIdentity and retrieveIdentity functions

If we gather all the elements studied in the previous paragraphs, we can expose two functions:

# Integrate with account creation and login

The next step is to call these functions when creating the account in the application and when connecting.

To create it during account creation:

To retrieve upon login:

Since the identity is only stored in memory in the browser, if you open a new tab, you will have to retype the password. To get around this problem, we do not try to get the logged-in user's profile from the server:

We will see later how to make this identity persist in the browser.

WARNING

Here we put aside a major security concern: the authentication password should not be used as is to protect the identity. The authentication method must be modified (with a pre-derivation of the password) so that the application server cannot know the password. A dedicated guide is available here.

# Encrypting & decrypting messages

To perform message encryption and decryption, you need to:

  • create a shared encryption session between the recipients;
  • encrypt messages before sending them;
  • decrypt messages after reception.

# Encryption Session

To create a shared encryption session between users userId_1 and userId_2 in the roomId_1 chatroom, we proceed as follows:

This returns an EncryptionSession with a new unique sessionId assigned by the server.

In this project, we put the chat room identifier roomId in metadata.

To encrypt a message with a session, we proceed as follows:

This will give a string of the form:

'{"sessionId":"0000000000000000000000","data":"8RwaOppCD3uIJVFv2LoP3XGXpomj0xsMv4qmMVy30Vdqor2w0+DVCXu3j13PEyN2KfJm6SiSrWDRMDziiiOUjQ=="}'

We can retrieve an instance of the session, either with the sessionId, or directly with the encrypted message:

Once the session is retrieved, it can be used to decrypt a message:

You can also add / remove recipients from the session:

For more details about the sessions, you can consult the dedicated guide.

# Integration in a chat room

To integrate these functions in the chat, three elements must be modified:

  • the sending of messages, which must now encrypt for the recipients of the chat;
  • the reception of messages, which must now be decrypted;
  • the management of the members of a chatroom, which must now transpose the members of a chatroom into cryptographic rights.

# Encryption upon sending

We have to call the encrypt function each time a message is posted.

In the Chat.jsx file there is a handleSumbitMessage function that we will modify to encrypt:

Also, when creating a multi-user chatroom in ManageDialogRoom.jsx a 'Hello 👋' message is sent. It must be encrypted:

# Decryption upon receiving

We need to call the decrypt function each time a message is collected.

To do this we will create a couple of helper functions in Chat.jsx that will be used to use the same data model everywhere:

Let's modify the eventListener of the event room:messageSent:

We are going to modify the retrieval of the history of the messages at the loading of a room:

# Modifying the rights upon editing a room

When the room is multi-user, the creator of the room can add / remove members. The sessions allow to manage these movements.

To do this, when the creator of the room makes these movements on the room, he must make the same movements on the encryption session.

When a room is modified, the session associated with the room must be given during the dispatch:

In ManageDialogRoom.jsx before making the API call to the server to actually edit the room:

# Conclusion

We were able to quickly integrate encryption into this project, but there are still three 3 issues remain before going into production:

  • password pre-derivation;
  • identity persistence when opening a new tab by storing the identity in localstorage;
  • the generation of license tokens from the backend.