To get started quickly, we'll integrate the encryption & decryption features directly into the sample project, by password protecting the identity.
We will use the web version of the SDK
@seald-io/sdk with the password identity protection module
cd frontend npm install @seald-io/sdk @seald-io/sdk-plugin-ssks-password
For the moment, there are no changes to make to the backend.
To configure the SDK, you have to connect to your administration dashboard and get the following elements:
appId: unique UUID for your application;
JWT_SECRET_ID: unique UUID of the shared secret;
JWT_SECRET: shared secret corresponding to the
JWTSecretused to generate JWT.
apiURL: URL of the API server to use;
keyStorageURL: URL of the identity storage server to use.
JWT secrets can be generated in the settings, tab
For more information refer to this documentation.
To create a developer account, follow the first steps.
To instantiate the SDK, we proceed as follows:
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.
This requires generating a JSON Web Token called
signupJWT from the
JWT_SECRET, and the
# Generating a
The generation of a
signupJWT 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 will use a utility tool, provided by the SDK to simply generate JWT.
In production, you must not give the frontend knowledge of
JWTSecret. 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 JWT generation.
# 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
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.
For faster execution, as an advanced usage of the SDK, you can customize the password derivation into a
rawEncryptionKey and a
rawStorageKey, and pass these instead of the password to
ssksPassword.saveIdentity. For more details, see the "Customize the password derivation" section of the Identity Guide.
# Exposing a
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.
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_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
To encrypt a message with a session, we proceed as follows:
This will give a string of the form:
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.
Chat.jsx file there is a
handleSumbitMessage function that we will modify to encrypt:
Also, when creating a multi-user chatroom in
'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
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:
ManageDialogRoom.jsx before making the API call to the server to actually edit the room:
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.