Algorithms used in Krptn
To derive the encryption key from the credentials (or from anything actually) Argon2id from the LibSodium Library is used with 0.2GiB memory limit and 3 operations count (4 for password reset codes). These values were based of RFC-9106 and LibSodium’s documentation.
For symmetric encryption, we use the XChacha20-Poly1305 from LibSodium Library.
For asymertric encryption, we use LibSodium’s
crypto_box_easy API. To know which algorithms are used in that API, please see the list in LibSodium’s documentation.
Here is a brief overview of how Krptn works:
- User’s credentials are sent to the server
- Server derives encryption key from the credentials. It uses this encryption key to decrypt a “master” key which is unique to each user
- Server uses these keys to access the data
- The server creates another (randomly generated session key), and encrypts master key with it. The result of this is saved in a database
- This session key is set in the response as cookies
- When the client sends further requests, the session key (from the cookie) is used to decrypt the master key, and access the data
- When the user logs out of the service (or the authentication period expires), the result of step 4 is deleted from the database.
Observe that the plaintext key, or user data, is never saved to the DB. It is only stored in memory. This protects you from a database leak, but not from a full server compromise.
In order to change a password, the data does not need to be decrypted and re-encrypted. It is as simple as encrypting the old master key, with the new credentials.
A user can generate recovery codes that they can use to recover their account in case the password is forgotten. You can choose to email these codes to the user (therefore delegating trust to the email account), or any other way to handle this. It is also possible to split the codes in half, email the first half to a primary email, and send the 2nd half to secondary email - this way, for the hacker, they would need to compromise 2 emails instead of one.
The essence of this procedure works by wrapping the master key using the recovery code: we generate a random code and push it through a KDF (Argon2id, but we explain the specifics of this in the first section of this page), and encrypt the master key with it. After this, the recovery code can be used to decrypt the master key.
To prevent this from being brute forced during a DB dump, we have implemented recovery codes which are longer then usual, and used higher security parameters in the hashing functions.
These codes essentially work like additional passwords. But note that if they are lost, there is no way to recover the account.
Sharing data between accounts
It is possible to share data between accounts using asymmetric cryptography. Each user has its public/private key pair.
When sharing data, a common key is derived using asymmetric cryptography, which is used to encrypt data, such that both parties can decrypt it from the DB later.