Skip to content

1. Concept

LightJack05 edited this page Mar 12, 2025 · 1 revision

Caution

This article is out of date and needs to be updated!

The base ideology

AnonKey intends to reduce the impact of cyber attacks on every attack surface. To accomplish this, we attempt to encrypt data whereever possible.

We implement ad zero-knowledge encryption concept, which means that the server, at no point in time, knows, what the data is it is storing. Thanks to this, even a complete takeover of the server means that your credentials are still safe.

To protect your master password, it is never sent to the server in the first place. The KDF result that is sent to the server is hashed using Argon2id, together with a user-unique salt and a server-unique pepper.

The different actions employing the encryption concepts are outlined in detail below.

User creation

On user creation, the user enters a desired username, a master password, and a display name.

Firstly, using a Key Derivation Function (KDF) called PBKDF2, we derive a key for signin usage. To derive this key, the username is used as nonce.

This key, together with the selected username and displayname is then sent to the server.

The server receives the information from the frontend, and creates a new user. This user is given the username and displayname as properties. In addition to that, the server generates a salt specific to that user. The server then hashes the password using Argon2id, while utilizing the user salt, together with a server-specific pepper as salt for Argon2id.

Once the new user has been created, the server generates a new JWT web token, and signs it with the server specific key.

This JWT token is then returned to the client which can use it to authenticate to the server.

Sign in

When signing in to AnonKey, you enter your master password and your username. Once you confirm the signin, the frontend derives a key from you masterpassword, using your username as a salt. This derived key, together with your username is then sent to the backend, which validates the key against the Argon2id hash stored in the database.

If the hash matches the stored one, a new JWT token is generated and signed by the server, which is then returned to the client.

Saving a credential

When you save a new credential, the client first generates a new UUID using the backend API endpoint. This UUID is then used as salt to derive a key from the master password, using a KDF.

Then, the frontend generates salts for each field in the credential. These salts are then used as initialization vectors for the following encryption. The frontend encrypts the fields in the credential object (aside from the UUID) using AES, with the generated initialization vectors.

These encrypted fields, together with the initialization vectors are then sent to the backend for storage.

Retrieving a credential

When retrieving a credential (or multiple), the credentials encrypted data is first downloaded. Once fetched, the uuid is read, and the key to decrypt the credential is derived from the master password. This key, together with the fetched initialization vectors, is used to decrypt the credential, and display it.

Clone this wiki locally