Password hashing

Purpose

Argon2id is a memory-hard password hashing and password-based key derivation function (KDF). It takes the following parameters:

  • A password.

  • A 128-bit random salt.

  • An iteration count.

  • A memory size in bytes.

Usage

DeriveKey

Fills a span with output keying material computed from a password, a random salt, an iteration count, and a memory size in bytes.

Argon2id.DeriveKey(Span<byte> outputKeyingMaterial, ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int iterations, int memorySize)

Exceptions

ArgumentOutOfRangeException

outputKeyingMaterial has a length less than MinKeySize.

ArgumentOutOfRangeException

salt has a length not equal to SaltSize.

ArgumentOutOfRangeException

iterations is less than MinIterations.

ArgumentOutOfRangeException

memorySize is less than MinMemorySize.

InsufficientMemoryException

Insufficient memory to perform key derivation.

ComputeHash

Fills a span with an encoded password hash computed from a password, a randomly generated salt, an iteration count, and a memory size in bytes.

Argon2id.ComputeHash(Span<byte> hash, ReadOnlySpan<byte> password, int iterations, int memorySize)

Exceptions

ArgumentOutOfRangeException

hash has a length not equal to MaxHashSize.

ArgumentOutOfRangeException

iterations is less than MinIterations.

ArgumentOutOfRangeException

memorySize is less than MinMemorySize.

InsufficientMemoryException

Insufficient memory to perform password hashing.

VerifyHash

Verifies that an encoded password hash is correct for a given password. It returns true if the hash is valid and false otherwise.

Argon2id.VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> password)

Exceptions

ArgumentOutOfRangeException

hash has a length less than MinHashSize or greater than MaxHashSize.

FormatException

Invalid encoded password hash prefix.

NeedsRehash

Determines if an encoded password hash matches the expected iteration count and memory size. It returns true if the hash does not match and false if the hash matches.

Argon2id.NeedsRehash(ReadOnlySpan<byte> hash, int iterations, int memorySize)

Exceptions

ArgumentOutOfRangeException

hash has a length less than MinHashSize or greater than MaxHashSize.

ArgumentOutOfRangeException

iterations is less than MinIterations.

ArgumentOutOfRangeException

memorySize is less than MinMemorySize.

FormatException

Invalid encoded password hash.

Constants

These are used for validation and/or save you defining your own constants.

public const int KeySize = 32;
public const int SaltSize = 16;
public const int MinKeySize = 16;
public const int MinIterations = 1;
public const int MinMemorySize = 8192;
public const int MinHashSize = 93;
public const int MaxHashSize = 128;

Notes

The best defence against password cracking will always be to use strong passwords. For example, diceware with 6+ words.

Here are some example parameters for different scenarios:

Source
Iterations
Memory (bytes)
*Delay (ms)

libsodium's interactive

2

67108864​

51

RFC second recommended option

3

67108864​

72

libsodium's moderate

3

268435456

314

libsodium's sensitive

4

1073741824

1745

*These delays are for my desktop (a gaming PC). You should perform benchmarks on a typical device for your application using BenchmarkArgon2.NET.

The parallelism is always 1 for deriving keys/hashes in libsodium. However, hashes with a parallelism greater than 1 can be verified.

Libsodium also supports Argon2i, which is more side-channel resistant but less GPU resistant. However, Geralt only supports Argon2id because it is the mandatory and recommended variant in the RFC plus there are attacks against Argon2i.

Last updated