2
$\begingroup$

By my understanding, a key derivation is when you take some data, say a password, and use a function to convert it into a number that can be used as a secret key in say elliptic curve cryptography. Argon2 uses a random salt when hashing, which necessitates that the hash is different every time despite the same password being used. If the hash is different, how can it be used to represent the same secret key?

$\endgroup$
5
  • 2
    $\begingroup$ Does this answer your question? Encrypt a file with AES using a secret key derived with Argon2 and you store the extra information. $\endgroup$
    – kelalaka
    Nov 5 '21 at 8:13
  • 1
    $\begingroup$ What you describe in the question is actually common with all KDFs that support a salt. @kelalaka While I agree the linked question has some in overlap with this one, the setting and the context are quite different from a comprehension perspective. $\endgroup$
    – DannyNiu
    Nov 5 '21 at 13:20
  • 1
    $\begingroup$ @DannyNiu I've already mentioned that as keep this information with..., if the OP is asking why do we remember the salt, the answer is obvious, the PBKDFs and KDFs are all deterministic, so if you input the same values you will get the same result. This is what we want from the Random Oracles, once we get a value for an input, we want the same value when we asked with the same input. and the last part always uses a random salt for hashing... I think I've covered all. $\endgroup$
    – kelalaka
    Nov 5 '21 at 13:26
  • $\begingroup$ @DannyNiu wrote one to cover all, may be I've missed some part, though some need to be copy and paste... $\endgroup$
    – kelalaka
    Nov 5 '21 at 14:03
  • $\begingroup$ @kelalaka that question actually answers my questions, thanks $\endgroup$
    – Manglemix
    Nov 5 '21 at 20:32
2
$\begingroup$

By my understanding, key derivation is when you take some data, say a password, and use a function to convert it into a number that can be used as a secret key in say elliptic curve cryptography.

Yes, this is correct, however, keep in mind that your password should have good enough strength to protect from brute-forcing. A common way is using the dicewire or Bip39 like password mechanisms, see in xkc936.

Once you derive the key $k$, then this is your private key, and $[k]G$ is your public key in ECC with the base point $G$ of the curve. Erase the $k$ after using, even don't store it in the memory, and keep your password safe!

Argon2 uses a random salt when hashing, which necessitates that the hash be different every time despite the same password being used.

Yes, that is correct, too. You may consider this like that with all of the parameters of the Argon2, you run a deterministic function. The same input will result from the same output. This is what we want from the hash functions, password hash functions, and Random Oracles; be deterministic; the same input must result in the same output.

Using different salt is used for deriving more than one key from a password. The salt at the same time is a good countermeasure aginst the rainbow tables where applicable.

If the hash is different, how can it be used to represent the same secret key?

To get the same key, you need to use the same parameters; the same password, the same salt, the same iteration, the same memory usage, and the same parallelization. Parameters apart from your password must not necessarily be secret, they can be stored openly. For example, this kind of information is stored in LUKS header, the important part is to keep your password secret all the time.

One must store these parameters when deriving the key from the password.

How is Argon2 used for key derivation?

First, decide your target security; i.e. how much do you want the life of the attacker is hard. Adjust the number of iterations, degree of parallelization, and memory usage according to your target security. Once you have decided, generate a uniform random salt. Determine the desired key size, like 256 bits (or 32 bytes). Now you are ready to use Argon2 with this information.

You supply your information to Argon and decide your target security;

Usage:  ./argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m memory] [-p parallelism] [-l hash length] [-e|-r] [-v (10|13)]
        Password is read from stdin
Parameters:
        salt            The salt to use, at least 8 characters
        -i              Use Argon2i (this is the default)
        -d              Use Argon2d instead of Argon2i
        -id             Use Argon2id instead of Argon2i
        -t N            Sets the number of iterations to N (default = 3)
        -m N            Sets the memory usage of 2^N KiB (default 12)
        -p N            Sets parallelism to N threads (default 1)
        -l N            Sets hash output length to N bytes (default 32)
        -e              Output only encoded hash
        -r              Output only the raw bytes of the hash
        -v (10|13)      Argon2 version (defaults to the most recent version, currently 13)
        -h              Print argon2 usage

Note that the Argon2 has three types;

  • Argon2d is faster and uses data-depending memory access. Data dependency immediately enables side-channel. This is suitable for cryptocurrencies and applications with no threats from side-channel attacks.

  • Argon2i uses data-independent memory access and this is preferred for password hashing and password-based key derivations.

  • Argon2id In the first half of the first iteration works as Argon2i and for the rest works as the Argon2d. This enables both side-channel protection and time-memory trade-off.

and form draft-irtf-cfrg-argon2-03;

If you do not know the difference between them or you consider side-channel attacks as viable threat, choose Argon2id.

$\endgroup$
2
$\begingroup$

It is true, you use a randomly generated salt with argon2i/argon2d/argon2id. However that random salt only needs to be generated a single time. You need to know the salt and parameters used in argon2 hash-generation in order to validate that hash later.

Some libraries offer encoded hash output for argon2. Encoded output stores the hash/paramaters/salt all in a single string. This encoded string can then be split out into hash/params/salt at the time you go to verify the hash.

This Defcon talk is somewhat recent and explains some of the technical implementation with regard to argon2: https://youtu.be/4Tn71-1GN20?t=1271

$\endgroup$

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