2
$\begingroup$

The Argon2 specs claim that Argon2 can be used both for password hashing and key derivation.

I want to generate from a single password both a hash for authentication and a secret key to use for encryption. (It would be nice if this could be generalized to any (reasonable) number of hashes and keys.)

From the specs, it is not clear to me why Argon2 can be used for key derivation; nor what related security property Argon2 has. (That would presumably allow me to understand whether (and how) what I want to do is (best) achievable.)

I see three potential options:

  1. Use Argon2 to generate a single key, then use a key derivation function to generate two subkeys.
  2. Use Argon2 to generate a key of sufficient length to split it into a hash and a key of respectively desired length.
  3. Use Argon2 twice, with different associated data.

I would also be interested in knowing what general property I am after, independent of Argon2.

Informally, I think what I want is a function that from non-uniform random input (passwords) generates pseudorandom output. Which is apparently what a key derivation function does, as per the HKDF paper. In this case, any of the three options above should work, I think.

This answer claims that "all the output behaves as independent random bits", but I do not understand why.

This answer is positive to essentially the same question, but for PBKDF2.

$\endgroup$

1 Answer 1

3
$\begingroup$

TLDR: use #1, perhaps with Argon2 at minimal security level as the KDF.

The three options work, and are secure if Argon2 matches it's design goals, which we have no reason to doubt, under the reasonable assumption that even with the strengthening given by Argon2, the choice of password makes a 128-bit security level acceptable.


I do not recommend to "Use Argon2 twice, with different associated data" (#3) if both uses must be performed in the same application (e.g. one output is used to verify the password and the other as key to AES-GCM). That's because two invocations of Argon2 doubles the execution time, or reduces the achievable security by 1 bit for a given execution time. If we can afford that doubling of computational cost, from a security standpoint when the password is the weak spot, we are better with a single Argon2 computation using twice as much resources, as in #1 and #2.

The "split" (#2) option is initially simpler, but (as noted in comment) the Argon2 RFC security claim limits security to $2^{128}$ Blake2b invocations when one of the output segment is known (but the password is usually considered a weaker spot even with the strengthening given by Argon2). Also, #2 can't be safely extended unless we spare enough tag for extension (which can be per the method of #1): we want that the extensions remain secure under the assumption the other output values are disclosed, thus need spare Argon2 tag, but extending the size of the tag breaks compatibility, because in Argon2 the tag length influences the whole tag value.

The "KDF" (#1) option has the advantage of clean extensibility, e.g. to a new type of key, like an RSA private key. It's also gives a better assurance than #2 for independence of the outputs. That's limited by the KDF security; the maximum entropy in the tag output by Argon2, which is at least nearly 256 bits; and the weakness of the password of course. In principle #1 is even slightly better from the standpoint of independence of the outputs if there in a lot of entropy in the password input; but then we wouldn't need Argon2.

I recommend that the tag size for #1, or the spare tag size for #2, is set to at least 32 bytes (256-bit), because we can at almost no cost.

In #1 we need a KDF. It can be a standard one (of the fast breed), including Argon2 with minimal cost parameters.


what general property I am after

A purposely-slow password-to-hash/key derivation function is often designated password hashing (function), or password-based key derivation function (which is more descriptive but has a namespace collision with the technically poor and obsolete PBKDF2 or it's ancestor PKDF1), or key stretching (function), sometime entropy stretching (function).

Prepending a memory hard prefix, as in memory-hard (password-based key derivation) function, adds that the transformation mobilizes the size and bandwidth of memory, proportionally to the number of instances running in parallel for different key/password input, which greatly helps against password cracking. That concept was pioneered to some degree by bcrypt, extended and formalized by Scrypt (which remains a decent choice for password-to-hash/key transformation), and polished in Argon2.

As for the property that the output can be safely split (for #2), I know no specific name. It follows from the property that the output remains computationally indistinguishable from random with both less work than finding the key/password by brute force, and less work than some claimed security level for distinguishing the output from random. I know no more specific name. It's a desired property of a KDF.


Revision: I significantly revised the answer following the comment below, to take into account the quoted security claim of Argon2. And as a consequence I downgraded #2. Independently, I added that it's safely extensible only if there is spare tag for that. Also I simplified and generalized the property in the last paragraph, my original wording (in the above comment) was unnecessarily complicated.

$\endgroup$
1
  • 1
    $\begingroup$ "the property that each bit of the output remains computationally indistinguishable from random knowing the other output bits and all inputs of the transformation except the password/key" - I do not see this property advertised for Argon2. Why can we assume Argon2 has it? RFC 9106 claims "to distinguish the output of the keyed Argon2 from random, a minimum of (2^(128),2^length(K)) calls to BLAKE2b are needed", but this requires a key. It seems reasonable, however, that a similar statement holds when only a password is used. $\endgroup$ Oct 27, 2022 at 18:13

Your Answer

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

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