2
$\begingroup$

Suppose one has a password manager, based on symmetric cryptography, that requires a master passphrase to be unlocked. Argon2 is used for deriving a secret key from the master passphrase.

I need several secret keys to encrypt different components, so I'm faced with a choice:

  1. Output more material using Argon2. For example, If I need four secret keys, tell Argon2 to output $4 \cdot 32 \cdot 8 = 1024$ bits, and then split this output into four secret keys.

  2. Create only a master secret key with Argon2 and use the master key to encrypt several other randomly generated secret keys.

What are the different implications of using one option versus the other?

Also, what is the maximum number of bits that it is safe to derive from a master passphrase using Argon2?

What are the different keys for?

Each entry in the main content of the encrypted database is a key-value pair, where the key is, e.g., the address of a Web site, and its associated value is the password for the user's account on the Web site.

A requirement for the assignment (it's a bit artificial, but whatever) is to enable fast access to the password given its key (as in key-value), even when there are many key-value entries. The solution I thought of is to encrypt each entry separately and use an auxiliary encrypted data structure that would map a key (as in key-value) to its entry in sub-linear time. A hash-table approach would perhaps be the best, but more complicated, so I decided I could use a sorted partially encrypted data structure to enable binary search.

Thus, I need a single secret key for AEAD of the main content, and three more keys for the auxiliary sorted data structure that enables faster access to the main content via binary search: the auxiliary structure is composed of two-element entries like so:

  1. a MAC tag of the key (as in key-value) of the corresponding entry in the main content
  2. the AEAD-encrypted index of the corresponding entry in the main content

Both entries are authenticated together using AEAD. So that's why I need the second and third key: for the unencrypted MAC tag and for the AEAD-encrypted index.

The auxiliary structure's entries are sorted by first element every time I add to the database or remove from it. Thus binary search over the entries by the first element enable $O(log n)$-time access to the database when just reading it, in the fast-path, when the database's integrity is preserved.

The fourth key is used for creating a MAC tag that authenticates all the AEAD MAC tags of the second element of all auxiliary data structure elements together. I also intend to pass the total number of entries as AEAD associated data.

$\endgroup$
2
  • 1
    $\begingroup$ What are the different keys for? That's potentially important for answering about the implications. The max output is listed in the RFC here; you don't need to worry. The second approach is more common with file encryption. Is this some pass type program? $\endgroup$ Mar 19, 2023 at 18:53
  • 1
    $\begingroup$ @samuel-lucas6 see edit $\endgroup$ Mar 19, 2023 at 21:09

1 Answer 1

5
$\begingroup$

In most cases you will want to generate a random master key and then encrypt that master key with a random nonce and a key derived from your password hash. This allows one to change the password without re-encrypting all the previously encrypted application data.

If you need additional keys for different uses in your application, you can deterministically derive them from the master key with HKDF and a domain-separation string.

Using HKDF is more future-proof than generating more random bits, more robust against changing requirements, as additional keys may be derived without needing to store them, and thus without needing to change the file format version.

Obviously you need to store the encrypted master key, the associated nonce, and salt for the password hash on behalf of the user or all encrypted data is effectively lost.

When the user wants to change their password, you generate a new salt for the password hash and a new nonce then re-encrypt the master key using the output of the password hash as a new key.

Be sure to use an authenticated encryption mode from a well-maintained library such as libsodium so that verification of the password is secure and automatic which you will know if the master key decrypts without throwing an error.

$\endgroup$
4
  • $\begingroup$ How long would you make the random master key? $\endgroup$ Mar 19, 2023 at 20:47
  • $\begingroup$ What's the point of using HKDF instead of just generating more random bits? $\endgroup$ Mar 19, 2023 at 20:47
  • 2
    $\begingroup$ @user2373145 you would need to store those additional keys, also encrypted by the master password, and then re-encrypt them on password change. By using key derivation you can get additional keys whenever you want as your application changes over time. $\endgroup$
    – rmalayter
    Mar 19, 2023 at 20:56
  • 2
    $\begingroup$ @user2373145 A 256-bit master symmetric key is sufficiently secure for any purpose, even assuming the existence of large scale quantum computers sometime in the future. $\endgroup$
    – rmalayter
    Mar 19, 2023 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.