Specification

This document specifies string encodings for the output of a password hashing function. Three kinds of strings are defined:

The specification calls for deterministic encoding: for a given function, set of parameters, salt value and output, producers MUST output the exact unique sequence of characters prescribed in this documentation. This allows testing with regards to explicit test vectors, and promotes interoperability by discouraging local variants. Consumers may accept other encodings, but are also allowed to reject any string that differs from the format herein described.

We define the following format:

$<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] where:

<id> is the symbolic name for the function <param> is a parameter name <value> is a parameter value <salt> is an encoding of the salt <hash> is an encoding of the hash output

The string is then the concatenation, in that order, of:

The function symbolic name is a sequence of characters in: [a-z0-9-] (lowercase letters, digits, and the minus sign). No other character is allowed. Each function defines its own identifier (or identifiers in case of a function family); identifiers should be explicit (human readable, not a single digit), with a length of about 5 to 10 characters. An identifier name MUST NOT exceed 32 characters in length.

Each parameter name shall be a sequence of characters in: [a-z0-9-] (lowercase letters, digits, and the minus sign). No other character is allowed. Parameter names SHOULD be readable for a human user. A parameter name MUST NOT exceed 32 characters in length.

The value for each parameter consists in characters in: [a-zA-Z0-9/+.-] (lowercase letters, uppercase letters, digits, /, +, . and -). No other character is allowed. Interpretation of the value depends on the parameter and the function. The function specification MUST unambiguously define the set of valid parameter values. The function specification MUST define a maximum length (in characters) for each parameter. For numerical parameters, functions SHOULD use plain decimal encoding (other encodings are possible as long as they are clearly defined).

The function specification MUST define a clear, unambiguous, deterministic encoding for each possible value of a parameter. Producers of strings MUST follow that encoding. Consumers MAY accept alternate encodings.

A parameter may be optional; if a parameter is optional, then the function MUST define the default value of the parameter. That default value MUST NOT be subject to context-dependent alterations (e.g. a value configurable in a system-wide setting is not an acceptable default). When a parameter is optional, producers MUST omit the parameter if its value is equal to the default value. The function MUST specify which parameters are optional and which are not.

The function MUST specify the order in which parameters may appear. Producers MUST NOT allow parameters to appear in any other order.

If the function expects no parameter at all, or all parameters are optional and their value happens to match the default, then the complete list, including its starting $ sign, is omitted. Note that the = sign may appear within the complete string only as part of a list of parameters.

The salt consists in a sequence of characters in: [a-zA-Z0-9/+.-] (lowercase letters, uppercase letters, digits, /, +, . and -). The function specification MUST define the set of valid salt values and a maximum length for this field. Functions that work over arbitrary binary salts SHOULD define that field to be the B64 encoding for a binary value whose length falls in a defined range or set of ranges.

The hash output, if present (in a "hash string"), MUST be the B64 encoding of the raw output of the hash function. The function specification MUST define the minimum, maximum and default output length.

B64

The B64 encoding is the standard Base64 encoding (RFC 4648, section 4) except that the padding = signs are omitted, and extra characters (whitespace) are not allowed:

A B64-encoded value thus yields a string whose length, taken modulo 4, can be equal to 0, 2 or 3, but not to 1. Take note that a sequence of characters of the right length may still be an invalid encoding if it defines some non-zero trailing bits in the last incomplete group; producers MUST set the trailing bits to 0, while consumers MAY ignore them, or MAY reject such invalid encodings.

Decimal Encoding

For an integer value x, its decimal encoding consist in the following:

Thus, a value is a valid decimal for an integer x if and only if all of the following hold true:

The C function strtol() and strtoul() can decode decimal values if their base parameter is set to 10.

Function Duties

A password hashing function that uses this specification for its salt and hash strings MUST specify the following:

It is RECOMMENDED to follow these guidelines:

API

The traditional Unix crypt() function is used both for password registration, and for password verification. It uses two string parameters:

char *crypt(const char *key, const char *salt);

The key is the password, while salt is a salt string or a hash string. In order to be compatible with how the crypt() function is used in existing software, the following must hold:

The third case departs from the prescription that string producers must always follow the deterministic encoding. This is done that way in order to support the common case of password verification: the salt value is the complete hash string as it is stored; the hash is recomputed, and the caller verifies that the exact same string is obtained (with a strcmp() call). This is the reason why the parameters and salt are reused "as is" in the output, even if they do not match the deterministic encoding prescribed in this document.

On the other hand, when the input salt string does not include the hash output, then this is initial registration, and we insist on using the unique valid deterministic encoding. The whole point is to try to avoid local variations that are detrimental to interoperability, while not breaking existing password hashes.

Argon2 encoding

For Argon2, the following is specified: