Salted variants of the SHA-2 digest

The SHA-2 algorithms described in RFC 6234 are a suite of cryptographic one-way digest algorithms that can be used to generate 256-bit, 384-bit, and 512-bit hashes of arbitrary amounts of data. One-way digests means that there is no known way to examine the resulting hash and determine the clear-text value used to generate it, other than simply trying every possible combination of clear-text values until you find one that matches. It is also computationally infeasible to generate collisions, that is, to find two different clear-text values that result in the same hash.

The SHA-2 digest algorithms are considered secure although there are two issues that can make them suboptimal on their own. The first is that providing the same clear-text input to the digest algorithm consistently yields the same hash. This makes it vulnerable to precomputed dictionary attacks in which attackers might use a dictionary that maps hashes to the clear-text values used to generate them and also makes it possible to determine whether two different users have the same password. This weakness can be addressed by combining the passwords with some amount of randomly generated data (called a salt) before computing the digest and then making the salt available in addition to the digest. The PingDirectory server only offers support for salted versions of the SHA-2 password storage schemes.

The second issue is that SHA-2 digests are fast to compute on their own. It is not unreasonable for an attacker to have access to hardware capable of generating billions of SHA-2 digests per second. This means that it can be faster to try large numbers of possibilities in an attempt to guess the password used to generate a digest through brute force. While strong passwords can still be highly resistant to this form of attack, weak passwords (for example, those using a smaller number or range of characters, and especially those based on dictionary words) can be quickly broken. Some other password storage schemes attempt to address this by requiring multiple rounds of digest computation, requiring parallel processing, or requiring large amounts of memory, but even in those cases, the best defense is still a strong password and ideally one that is combined with a second factor like a one-time password.

The PingDirectory server uses the salted 256-bit SHA-2 digest as the default password storage scheme for regular users, that is, for users other than root users and topology administrators.

Salted and unsalted variants of the SHA-1 digest

The SHA-1 algorithm described in RFC 3174 is a cryptographic one-way digest algorithm that was in widespread use for many years as a leading mechanism for encoding passwords, and some directory servers in widespread use can still use it as the basis for their default password storage schemes. However, researchers have been able to devise attacks against the SHA-1 digest that make it possible to generate collisions under some circumstances (albeit with considerable computational effort). As such, it is no longer recommended for use in encoding new passwords.

The PingDirectory server supports both salted and unsalted variants of the SHA-1 digest. Support for the salted variant is enabled by default, but you should only use it as a deprecated scheme for the purpose of migrating passwords to a more secure alternative, like one of the SHA-2 digests or one of the PBKDF2, Argon2, bcrypt, or scrypt key derivation functions. Support for the unsalted SHA-1 digest is disabled by default and should only be enabled if needed for compatibility with legacy systems.

The PBKDF2 key derivation function

The PBKDF2 (password-based key derivation function, version 2, as described in RFC 2898) is a standard algorithm for encoding passwords and generating cryptographic keys from passwords. The PBKDF2 algorithm uses a salt to make it resistant to precomputed dictionary attacks, and it also uses multiple rounds of computation to increase the amount of processing required to compute the encoded representation for the password and slow down the rate at which attackers can make guesses in brute-force attacks.

Note:

While the PBKDF2 function is a well-defined standard, the specification only covers the algorithm used to derive a key using the password, salt, and number of rounds as inputs.

There is no standard encoding that combines the resulting digest with the salt and number of rounds used to generate that digest. This means that while multiple products can support using the PBKDF2 algorithm to encode passwords, the way they represent the encoded passwords might be different. The PingDirectory server uses an encoding that attempts to be as compact as possible, helping to minimize the on-disk and in-memory footprint for the data, and as a result it is very likely to be different from the encoding used by any other product. The encoding that we use is constructed as follows:

  1. The first byte represents the encoding version and the message digest algorithm. Possible values include:
    • 0x00 — The SHA-1 digest (PBDKDF2WithHmacSHA1)
    • 0x01 — The 256-bit SHA-2 digest (PBDKDF2WithHmacSHA256)
    • 0x02 — The 384-bit SHA-2 digest (PBDKDF2WithHmacSHA384)
    • 0x03 — The 512-bit SHA-2 digest (PBDKDF2WithHmacSHA512)
  2. The second byte represents the number of bytes used to hold the salt. The storage scheme supports salts from 8–127 bytes (64–1016 bits). By default, the server generates 16-byte (128-bit) salts.
  3. The byte used to indicate the salt length is followed immediately by the bytes that comprise the salt.
  4. The next two or four bytes holds the iteration count used for the algorithm. If the iteration count is less than or equal to 32,767, then it is encoded in two bytes. If the iteration count is greater than or equal to 32,768, then it is encoded in four bytes, and the most significant bit of the first byte is set to 1.
  5. The remainder of the encoded password is the output of the PBKDF2 algorithm generated from the clear-text password and salt using the indicated algorithm and iteration count.

The bytes resulting from the above steps are base64-encoded, and the whole string is preceded by a prefix of “{PBKDF2}”.

Note:

Even though the encoding that the PingDirectory server uses might differ from that of other servers, as long as those other servers use the same standard algorithm to derive the key, it should still be possible to convert between their encoded representations and the one that the PingDirectory server uses. It should therefore be possible to migrate PBKDF2-encoded passwords between systems.

The PingDirectory server uses the PBKDF2 password storage scheme by default for root users and topology administrators.

See the config/sample-dsconfig-batch-files/use-pbkdf2-password-storage-scheme.dsconfig batch file for more information on configuring and using the PBKDF2 password storage scheme.

The Argon2, bcrypt, and scrypt key derivation functions

The Argon2, bcrypt, and scrypt key derivation functions are strong, highly regarded functions for encoding passwords. They are all intentionally expensive as a means of making them more resistant to password guessing attacks. The bcrypt algorithm uses a cost factor to increase the amount of processing required. The script and Argon2 algorithms also employ memory access and parallel processing as additional techniques for increasing the cost of generating large numbers of passwords.

Unlike the PBKDF2, the Argon2, bcrypt, and scrypt algorithms do have predefined encodings that combine all of the necessary metadata like the salt, cost factors, and other settings used to compute the resulting key. As such, the format that the PingDirectory server uses for passwords encoded with these schemes should be compatible with the format used by other servers that support them.

See the use-argon2-password-storage-scheme.dsconfig, use-argon2-password-storage-scheme.dsconfig, and use-scrypt-password-storage-scheme.dsconfig files in the config/sample-dsconfig-batch-files directory for more information about configuring and using these password storage schemes.

The crypt password storage scheme

The PingDirectory server also provides support for a suite of password encodings that match those often used by Linux and UNIX-based systems. This includes the legacy UNIX crypt algorithm which uses the DES encryption algorithm and an extremely small 12-bit salt, as well as stronger, multi-round variants that are based on the MD5 and SHA-2 digests. It can support authentication with any of these variants, but it only uses one of them when encoding new passwords.

Only the 256-bit and 512-bit SHA-2 variants are considered secure, and they are the only ones that should be used for encoding new passwords. The 256-bit SHA-2 variant is used by default. However, because of the potential to support the weak DES-based and MD5-based algorithms, we discourage the use of the crypt password storage scheme unless absolutely required for compatibility.

The AES encryption algorithm

The PingDirectory server also supports storing passwords in a reversibly encrypted form using the AES cipher algorithm. Because this storage scheme uses reversible encryption, there is a much greater risk that passwords encoded with this scheme could be exposed in the event of a data breach. As such, use of this password storage scheme is highly discouraged unless you need to use an authentication mechanism that requires access to the clear-text password, such as the CRAM-MD5 or DIGEST-MD5 SASL mechanisms.

Custom password storage schemes

Use the UnboundID Server SDK to implement support for custom password storage schemes using whatever encoding you want. The Server SDK provides two types of extensions for this purpose:

  • The PasswordStorageScheme class provides support for encoding and validating passwords using only the clear-text password and information in the configuration for that storage scheme.
  • The EnhancedPasswordStorageScheme class also provides access to other information in the user’s entry, as well as a potential set of updates that are being applied to that entry. This option might be required if the password encoding depends on other information stored in the user’s entry, such as if the salt or other encoding metadata is stored separately from the encoded password.

A custom password storage scheme might be required if you need to migrate data from another system into a PingDirectory server instance, and the migrated data includes passwords encoded in a format that the PingDirectory server does not support.