# 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:
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.
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:- normalizes the password canonically with the method
String#normalize
(opens new window); - transforms the normalized password into
Buffer
;
- normalizes the password canonically with the method
- we define
hashPassword
which encodespassword
andsalt
and derives them withscyrpt-js
configured with robust parameters, then returns the result asPromise<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
.
DETAILS
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.