(1)
Setup:
- Generate a random salt and store somewhere safe.

Note that it should not be required to keep the salt secret.

Encryption:
- Read the salt from its location and the master password from the
console. Use those to generate a key with crypto_argon2i.

I don't know crypto_argon2i. I'd use the standardized HKDF2 scheme to derive
the key.

- Read password from the console (or generate randomly) and encrypt it
with the key and a randomly generated nonce using crypto_lock.
- Write the mac, nonce, and encrypted password to a file.

I'm not sure why you would need a mac if you don't use a malleable encryption
scheme.

How do you address the (non-encryption) key part of the key-value store?
If you planned to use the filename as key (e.g. "amazon.com"), see my other
mail.

Decryption:
- Read the salt from its location and the master password from the
console. Use those to generate a key with crypto_argon2i.
- Read the mac, nonce, and encrypted password from the file.
- Decrypt the password using the mac, nonce, and key using crypto_unlock.

It's not clear to me if it's okay to use the plain crypto_argon2i with
just a fixed secret salt.

Should be fine, but the salt should not be secret (you need to sync it
between devices where you want to use this system after all). The point is that you can give your encrypted database as it is stored on disk to anyone
and they would not be able to derive anything (you care about) from it
without the master password. Depending on what you care about, the whole
password storage thing get's more and more complex, but this is a nice
development process where you can add features one after another:

- Okay to publish which sites I use?
- Okay to publish how long my passwords are (roughly)?
- Okay to publish when I changed the password for a specific site regularly?
- Okay to publish when I changed my master password?
- Okay to publish when I changed anything?

In the end the master password should be the only thing that needs to be kept secret and you can easily "sync" that between devices by remembering it. ;)

Keeping the salt fixed is okay as long as you don't change the content it is
used for, in this case the master password.

A related scheme might be to use
crypto_argon2i_general with a salt generated for each encryption and a
single saved key. Then, the salts could be stored as plain text the
output file (and probably authenticated with crypto_lock_aead).
Perhaps one benefit is if someone somehow figured out the encryption
key for one password, they still wouldn't be able to decrypt the
others.

(2)
Setup:
- Generate a random salt.
- Read a master password from the console and generate a master key
from it and the salt using crypto_argon2i.
- Use crypto_key_exchange_public_key to compute the master public key
from the secret key.
- Save the salt and the master public key somewhere safe.

Encryption:
- Read the master public key from its location.
- Randomly generate a single-use key, and compute a shared key from it
and the master public key using crypto_key_exchange.
- Compute the single-use public key using crypto_key_exchange_public_key.
- Read password from the console (or generate randomly) and encrypt it
with this shared key, a randomly generated nonce, and the single-use
public key as additional data using crypto_lock_aead.
- Write the mac, nonce, single-use public key, and encrypted password to a file.

Decryption:
- Read the salt from its location.
- Read a master password from the console and compute the master key
from it and the salt using crypto_argon2i.
- Read the mac, nonce, single-use public key, and encrypted password
from the file.
- Compute the shared key from the single-use public key and the master key.
- Decrypt the password using the mac, nonce, single-use public key,
and shared key using crypto_unlock_aead.

For (2) I'm not sure if the nonce is necessary or not, since passwords
are encrypted with randomly generated single-use keys (so maybe a
fixed value is sufficient; it is still only used once per key).

The main differences are that (1) requires the master password for
every encryption, but not setup, and (2) requires the master password
only for setup. I think (2) is more similar to how gpg works.

Perhaps somebody who knows more about these crypto primitives could
point out any flaws with these schemes.

That one seems a bit complicated due to the creative (ab?)use of key exchange. Using asymetric encryption is the right approach though if you aim for not needing the password on encryption and I couldn't come up with a simpler system
quickly, so maybe it's not so bad after all. ;)

Reply via email to