# KDF Salt: How/When is it Okay for it to be public?

Post Structure:

1. Prior source material studied

2. Question & Details

3. Assumed threat model

4. Example

5. Assumptions

6. Clarifications

Prior source material studied

0.1. RFC 2898

0.2. HAC (Handbook of Applied Cryptography)

0.3. Crypto 101

0.4. SE answers (ex: If attacker knows salt and hash, how is salt effective?) and (Use of salt to hash a password)

0.5 2018 DBIR

Question:

How is a KDF using a known salt and a low-entropy password more secure than the so-called "completely broken and not at all secure" primitive hash with salt?

1.1 Details:

Based on the available subject material, the KDF salt is not required to be kept a secret.

Does the recommendation imply a starting assumption in the threat model that the user-provided secret-key/password will always have sufficiently high entropy, or won't be an instance of weak one? Or does the recommendation only apply to specific instances where the same or different data is encrypted regularly with a different salt/key each time?

The author of Crypto101 writes this about generic Crypto Hash Primitives:

"While this [rainbow tables based on a known single salt] would have been prevented by using a different salt for each user, systems that use a cryptographic hash with a per-user salt are still considered fundamentally broken today; they are just harder to crack, but not at all secure."

If the threat model always assumes (as it should) that the user-provided secret key could be weak, then how does using KDF with a known salt become more secure than the aforementioned broken pattern of using a Hash Primitive with unknown (high-entropy) salt? (see Clarifications for answer to an obvious counter here)

(Aspects of) Assumed threat model for the question:

2.1 The user creates a low entropy password (TW37VE), which needs to be stored, and used for login.

2.2 The threat actor will use the same kdf (with correctly-guessed iteration) to compute the key from this common low-entropy password.

2.3 Salt needed to add entropy to the user-provided password (edit: a typo originally stated 'secret key' instead of password here) -- which is assumed to be from low-entropy space -- will be assumed here to be known to the threat actor (based on the recommendations in the documents).

2.4 The slow-computation/high-memory cost of KDF is bearable, if only for access to even a single user data: for instance, it could be a case of an insider-threat actor willing to access data for a specific user.

2.5 Internal/Insider threat actors: Based on 2018 DBIR, 28% of all the reported data breaches involved an insider/internal actor. The threat model thus accounts for an internal actor as a potential threat even in the absence of an external one. Thus, the need to secure the salt as well. (See clarifications for answer to the obvious counter)

Example:

Used KDF:

Say for password TW37VE, PBKDF2_SHA256 generates a key with the random salt 0CE@N's, and 100000 iterations, such that the derived key is:

kdf(TW37VE, 0CE@N's, 100000) : pbkdf2-sha256$$100000$$OCE@N's$!@#%^& Threat KDF: kdf(harvested-weak-password = TW37VE, not-secret-salt = 0CE@N's, guessed-iterations = 100000): pbkdf2-sha256$$100000$$OCE@N's$!@#%^&

If a legitimate user could validate itself using the known low-entropy password and the retrieved salt, what would be the deterrant in case of an attacker armed with (a) the harvested password (or it's precomputed dictionary/rainbow hash), and (b) the not-kept-a-secret salt?

Even if it is trivial for the threat actor to scan-and-match the password against the, say 64-bit, salt key space, the resulting potential delay wouldn't hurt.

4.1. The non-random part of the derived key is irrelevant to the security model strength.

4.2. The attacker could just as well use pbkdf2-sha256 with the known salt, the harvested secret key, and the correctly-guessed iterations.

Clarification

5.1 The drawbacks of using certain primitive-based approaches are understood; and, so are and the advantages of random-salt KDF's in differentiating similar contents.

5.2 The question focuses on why a primitive-based pattern under the assumed threat model is said to be broken, whereas the KDF pattern which simply yields to similar threat models under similar conditions is considered as an improvement over the former.

5.3 The DBIR reported "28% internal actors" figure includes different types of actors with different actions, which -- although likely to be small -- in this case is assumed to be a developer from the application-server team gone rogue (or maybe it was always bad?).

5.4 The home-grown roll: there is a way to keep the salt encrypted without the threat actor having the access to the salt-decryption key unless the entire database server is compromised.

Summary:

To reiterate, how does NOT keeping the kdf salt a secret help, when exposing it could have the potential to be harmful, and security-equivalent of an unsecure primitive method?

How is a KDF using a known salt and a low-entropy password more secure than the so-called "completely broken and not at all secure" primitive hash with salt?

A password hash or password based key derivation function (PBKDF) is more secure as it also uses key stretching techniques (a work factor or iteration count) to make it more difficult for an adversary to "guess" passwords. Those functions could be memory hard to make it even harder for an adversary to attack the password. As the work factor only adds a constant time factor the protection it offers is still limited though.

Note that this is particular to Password Based KDF's. There are also KBKDF's such as HKDF that may use a salt, but do not offer key stretching.

If the threat model always assumes (as it should) that the user-provided secret key could be weak, then how does using KDF with a known salt become more secure than the aforementioned broken pattern of using a Hash Primitive with unknown (high-entropy) salt? (see Clarifications for answer to an obvious counter here)

The user doesn't provide a (symmetric) key, the user provides a password. Users are notoriously bad in entering 16 byte binary values.

A "secret salt" is also called a pepper. If it is possible to keep a secret pepper then yes, that would be more secure than using a salt, even if the latter is used within a PBKDF. If the pepper value is the same for multiple users then you should still use an additional salt though; otherwise users with the same password would be easily identified.

Generally it is assumed that there isn't a secure key store available, so the use of a pepper is simply not feasible. Obviously the pepper cannot just be stored as plaintext in the same database.

As KDF's provide explicit inputs for password and salt (but unfortunately often not for separate salt and pepper) it would still be better to use a key based KDF or PBKDF with an iteration count of 1 than a cryptographic hash, if just to have a clear separation between the inputs before hashing them.

For instance $$\text{Hash}(P_0P_1\|S_0)$$ and $$\text{Hash}(P_0\|S_0S_1)$$ could hash to the same value, while this isn't expected for $$\text{KDF}(P_0P_1, S_0)$$ and $$\text{KDF}(P_0, S_0S_1)$$.

• edit in progress... – aandotherchars Oct 17 '18 at 14:02
• I understand the below mentioned part of the answer; my question is post-that-fact: even after the key-extension & computation--/memory++ features, given that user provided password (not key) could be weak & harvested, & that the entropy-adding salt could be public per recommendations, the DK remains just as exposed as the primitive based hash. Thus, adding no security unless the salt is kept secret. [ "it would still be better to use a key based KDF or PBKDF with an iteration count of 1 than a cryptographic hash, if just to have a clear separation between the inputs before hashing them" ]. – aandotherchars Oct 17 '18 at 14:21
• What do you mean with "harvested"? You'd have to try all weaker password combinations using the given salt, and a PBKDF slows down the computation. If the password is super weak then sure, you're in trouble. And if it can be helped you should not expose the salt. With the salt being public it is meant: storing it next to the password hash or ciphertext. I would not recommend publishing as it would allow precomputation of password hashes and then validating the quesses after the computation. – Maarten Bodewes Oct 17 '18 at 14:58
• By harvested I meant the pre-computed weaker passwords the threat actor could use. Even with salt stored in db, KDF seems to offer no better security given that user will create weak passwords and the salt is visible. The time factor might slow it down, but even one leaked account is a broken system. Assuming a threat model where the attacker has access to the server, KDF makes no difference other than slow down the attacker to maybe getting hands on fewer weaker password accounts. – aandotherchars Oct 17 '18 at 15:17
• Of course, because a PBKDF just adds a constant computation cost to the attacker. – Maarten Bodewes Oct 17 '18 at 15:59

The purpose of the salt isn't to make the computation of the key from the password more difficult. The purpose is to make it unique, even if multiple users share the same password.

If 1000 users share the password "password1" and there's no salt, then an attacker with access to the password hash database only has to guess correctly for one of those users, all the rest of the hashes are identical.

If 1000 users share the password "password1" and they each have a unique salt, then an attacker with access to the password database has to guess correctly for each user in turn, all the hashes are unique. Thus, it's 1000x more difficult for the attacker to get the hashes of ALL the users. The difficulty of getting the hash for ANY SINGLE user hasn't changed.