Design decisions

Algorithms

To encrypt the information, this software makes use of the secret key encryption of the PyNaCL package. Currently the Salsa20 stream cipher is used for the encryption and Poly1305 for the data integrity. The key derivation is achieved using the Argon2 algorithm with the argon2i variant or the scrypt algorithm in combination with the Salsa 20/8 core algorithm and the Pbkdf2-SHA256. Server can set the algorithm options (argon2i/scrypt parameters) that will be available to the user. Salt is calculated on the fly, and there are no precomputed salts.

How magic happens

When storing on server

Encryption

  • The server receives the plaintext and (optionally) a password

  • Using the password and the aforementioned key derivation function (kdf), a key is created - If a password is not given, a random one is generated on the fly

  • With that password derived key, the server encrypts the plaintext and stores the encrypted payload on the database

  • The server encrypts with the server key the primary key of the row that corresponds to the encrypted payload

  • The server generates random bytes and encrypts them with the server key to use as a duress key

  • The server sends back the server-key-encrypted primary key, the encryption key and the duress key, all url-safe encoded with base64

Decryption

  • The server receives a payload and a key

  • Decoding the payload, the server tries to decrypt it with the server key (if it fails, it assumes this is a no-store payload, see later-on for that scenario)

  • Using the decoded and decrypted payload it finds the id that corresponds to the encrypted payload row

  • The server tries to decrypt the user provided key with the server key
    • If that succeeds, it means this is a duress key. The server deletes the correspondin payload row and reports back that an invalid key / payload was provided. This is to completely hide the use of the duress key

    • If that fails, it means this is not a duress key. The server uses the user provided key to decrypt the payload and returns the plaintext

When not storing on server

Encryption

  • The server receives the plaintext and a password

  • Using the password and the aforementioned key derivation function (kdf), a key is created.

  • With that password derived key, the server encrypts the plaintext

  • The server sends back the password-derived-key-encrypted payload and the encryption key, all url-safe encoded with base64

Decryption

  • The server receives a payload and a key

  • Decoding the payload, the server tries to decrypt it with the server key and fails

  • Using the decoded user-key it decrypts the encrypted payload

  • The server returns to the user the plaintext

Notice here that there is no duress key. This is because the encrypted payload is not stored anywhere. This means that anyone who holds the key, applying the decryption procedure mentioned above will be able to decrypt the payload. This can happen at any time for as many times anyone wants. This information is persistent and the only way to stop this from happening is to make the payload or the key disappear. Be extremely careful when using this option

Questions?

For questions regarding these design choices, take a look at Questions and answers and if this doesn’t satisfy you, open an issue (for more details see Contributing).