# Pre-derivation of the password

In the previous step, we integrated the SDK by protecting the identity with a password, but this password is also used for authentication, which is not secure as it is, since the backend has knowledge of it during the account creation and at each connection.

In this step, we will add a "pre-derivation" of the password to ensure that the backend never has access to the password.

The branch on which this step is based is 1-quick-start (opens new window), the final result is 2-pre-derivation (opens new window).

# Explanation

Usually the authentication is done as follows:

uml diagram

The problem lies with the fact that the backend receives the password as is in such a protocol, and could therefore use it to decrypt the protected identity on SSKS.

The solution we recommend is to perform a so-called "pre-derivation" step on the password to prevent the server from knowing the password as is, even at runtime.

uml diagram

In the context of the example project, we will implement this pre-derivation in the service frontend/services/api.js and in the file frontend/utils/index.js:

# Pre-derivation function

The derivation function chosen is scrypt (opens new window), but any password derivation function like pbkdf2, bcrypt, argon2 or others would provide the same functionality.

The first thing to do is to install the scrypt-js (opens new window) package:

cd frontend
npm install scrypt-js

Then in the file frontend/utils/index.js:

  • we define encode which:
  • we define hashPassword which encodes password and salt and derives them with scyrpt-js configured with robust parameters, then returns the result as Promise<Buffer>.

# Using the pre-derivation function

The password must be pre-derived before the account creation and before the login.

As a salt, we use the concatenation (separated by |) of:

  • an arbitrary String for the application that will be embedded in the frontend code, set via the APPLICATION_SALT configuration variable, defaulting to 'sdk-example-project-salt;
  • the userId.

This is not a random salt because:

  • the frontend does not have the ability to store a random salt, a user can use a new browser at any time;
  • the backend is considered malicious, so it can't be trusted to store a random salt for each user, it could render an arbitrary false salt and get the result, and thus could determine if two users have the same password.

# Server side migration

In the example project, no migration step is planned, the database must be deleted and the users recreated.

If we want to perform migration of the passwords, it is not possible to do it offline since the server is not supposed to store the user's password, but a hashed and salted version.

A possible strategy is therefore to force a password reset for all users. More refined strategies can be considered depending on the case.

# Conclusion

We were able to add a password pre-derivation step to make the password protection robust, since in the example project it is also used for authentication.

It remains to be integrated before going into production:

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