Skip to content

Latest commit

 

History

History
108 lines (67 loc) · 11 KB

hashing.md

File metadata and controls

108 lines (67 loc) · 11 KB

Hashing

Use

BLAKE2

Faster than MD5, SHA-1, SHA-2, and SHA-3, yet as real-world secure as SHA-3. It relies on essentially the same core algorithm (borrowed from ChaCha20) as BLAKE, which received a significant amount of cryptanalysis as part of the SHA-3 competition.

It's available in many cryptographic libraries and is used in password hashing schemes and well-known software (e.g. WireGuard and the Linux kernel).

There are two main variants. In most cases, use BLAKE2b-256, -384, or -512. However, on 8- to 32-bit platforms, BLAKE2s-256 will be more performant.

The biggest weakness is the large number of variants (e.g. BLAKE2x to get an XOF), but this issue is hidden from users by cryptographic libraries.

SHAKE

Still part of the SHA-3 standard but faster than SHA-3 (similar to SHA-2) and an XOF.

SHAKE128 provides a 128-bit security level with at least a 256-bit output, and SHAKE256 provides a 256-bit security level with at least a 512-bit output.

To get the same security level as SHA3-256/SHA-256, you should use SHAKE256 with a 256-bit output. This provides 128-bit collision resistance.

SHA-3

Relatively slow in software, but the new standard, fast in hardware, well analysed, very different to SHA-2 due to the praised sponge construction, and has a higher security margin than the other algorithms listed here.

The main criticism aside from speed is that the security is over the top. Even the designers agree as they've developed reduced functions based on it. However, those alternative functions haven't seen much use compared to BLAKE2/BLAKE3.

BLAKE3

The fastest cryptographic hash in software when accelerated at the cost of receiving less analysis, having a lower security margin, and being limited to a 128-bit security level. It's also less accessible via cryptographic libraries than the other recommended algorithms.

However, it has the BLAKE legacy behind it and improves on BLAKE2 in that there’s only one variant that covers all use cases (e.g. a KDF and XOF too).

The speed is a huge bonus when using it as a MAC for Encrypt-then-MAC because it holds up against Poly1305 (from ChaCha20-Poly1305) and GHASH (from AES-GCM) when hashing enough data whilst providing stronger security guarantees (e.g. collision resistance for committing security).

SHA-2

The most popular hash function. It’s widely available in cryptographic libraries, still secure after many years of cryptanalysis, and offers decent performance.

However, unlike the other recommendations, it suffers from length extension attacks (please see the Notes section) and uses the Merkle-Damgård construction, which isn't used for new hash functions. It also wasn't the result of an open competition.

Thus, to take advantage of security improvements, a newer hash function should be used if possible.

Avoid

Non-cryptographic hash functions

For example, Meow Hash and error-detecting codes (e.g. CRC). These are not secure.

MD5 and SHA-1

Both are very old and no longer secure. For instance, there’s an attack that breaks MD5 collision resistance in 218 time, which takes less than a second to execute on an ordinary computer.

Obviously, don't use their older counterparts either (e.g. MD4 and SHA-0) because they're even less secure.

Streebog

It has a flawed S-Box, with no design rationale ever being made public, which is likely a backdoor. It's somehow available in VeraCrypt, but I've luckily not seen it used anywhere else.

Non-finalist SHA-3 candidates

For example, Edon-R, which is broken. Nobody uses these, and they've received less scrutiny than finalists.

SipHash

Despite the name, this is a MAC (please see the Message Authentication Codes section), meaning it requires a key. It's also not collision resistant.

Chaining hash functions

For instance, SHA-256(SHA-1(message)) or SHA-256d. This can be insecure (an inner collision means an outer collision) and is obviously less efficient than hashing once.

RIPEMD

The original RIPEMD has collisions and RIPEMD-128 has a small output size, meaning they're insecure.

Then the longer variants (e.g. RIPEMD-160) are still old, not long enough, unpopular, suffer from length extension attacks, and have worse performance and have received less analysis compared to the recommended algorithms.

Fun fact, RIPEMD-256 uses RIPEMD-128 internally, and RIPEMD-320 uses RIPEMD-160 internally. This means the longer versions provide the same security level as their half-sized counterpart, which isn't what you want.

Cryptographic hash functions nobody uses

Whirlpool, Tiger, SHA-224, and so on. These are all worse in one way or another than the recommended algorithms.

For instance, there are attacks too close for comfort on Tiger plus there are weird versions, Whirlpool is slower than most other cryptographic hash functions and only produces a 512-bit output, and SHA-224 only provides 112-bit collision resistance, which is below the recommended 128-bit security level.

128-bit hashes

These only provide a 64-bit security level when you want 128-bit security, which requires using a 256-bit output.

KangarooTwelve

From the people behind Keccak/SHA-3, much faster than SHA-3 and SHAKE, has a safe security margin, and has no variants. However, it's not that accessible, rarely used, and only offers 128-bit security like SHAKE128/BLAKE3.

Notes

These are not suitable for password hashing

Regular hash functions are fast, whereas password hashing needs to be slow to prevent password cracking. Furthermore, password hashing requires using a random salt for each password to derive unique hashes when given the same input and to protect against precomputation attacks.

These are not suitable for authentication

These algorithms are unkeyed. You need to use a MAC (please see the Message Authentication Codes section), such as keyed BLAKE2b-256 or HMAC-SHA-256, for authentication because they provide the appropriate security guarantees.

Beware of length extension attacks

MD4, MD5, SHA-1, RIPEMD, Whirlpool, SHA-256, and SHA-512 are susceptible to length extension attacks.

An attacker can use Hash(message1) and the length of message1 to calculate Hash(message1 || message2) for an attacker-controlled message2, without knowing message1.

Therefore, concatenating things (e.g. Hash(secret || message)) with these algorithms is a bad idea.

Use any of the non-SHA-2 recommendations instead because they're not susceptible. SHA-512/256, SHA-384, and HMAC-SHA-2 aren't either.

Concatenation requires care

When feeding multiple inputs into a hash function, you need to be careful to avoid canonicalization attacks. As this is mostly relevant for MACs, please read the Message Authentication Codes Notes section for more details.

Hash functions do not increase entropy

If you hash a single ASCII character, there are still only 128 possible values. Therefore, prehashing passwords before using a password-based KDF doesn't improve the entropy of the password.

Truncation

With a modern, fixed-length hash (e.g. SHA3-512), use the full standard output length if possible, meaning no truncation. This maximises the security level.

If the hash function lets you specify a range (e.g. BLAKE2b), use that instead of manual truncation.

The same is true for XOFs (e.g. SHAKE and BLAKE3) because that's what they're designed for. However, with XOFs, a larger output for the same input will also start the same.

If you can use a fixed-length hash that does the truncation for you internally (e.g. SHA-512/256), use that instead of manual truncation. This provides domain separation.

Otherwise, you can take the first n bits from the left to get an n-bit hash. This is safe, but you lose domain separation compared to the above.