I am confused about the notion of "pepper" in the context of storing hashes of users' passwords.

Definition 1: A pepper is a secret key

Looking around the Internet, for example here or here, a pepper is frequently defined to be a fixed and randomly chosen string that flows into the computation of a hash in one way or another. The main idea is that the pepper is stored separately from the salts (which are typically stored along with the password hashes in a database). For example, the pepper may be hardcoded into an application's code, or defined in an application's configuration.

Under this definition, the main differences to a salt are:

  • The pepper is the same for all users.
  • The pepper is stored separately from the salts.

(Apparently, the hope is that this improves security because the pepper is stored elsewhere, and an attacker who gains access to the database with the hashes and salts may still not gain access to the pepper. I'm not fully convinced, but let me not digress.)

But then, essentially, we are speaking about nothing else than a keyed hash function, where the key is called "pepper". In other words: this is a MAC. Now of course there are plenty of ways how to construct a MAC from a cryptographic hash function, and those ways that people come up with on the spot are usually no good, so if you look around you will often find the suggestion to use HMAC (or CBC-MAC etc.) if you want to use pepper, making it even more clear that a pepper is nothing but a secret key (see, e.g., here).

Definition 2: A pepper is an unknown salt

Another definition, to be found for example here, is utterly different. It states that a pepper is basically a (short, say 8 bits) random salt that you don't store. This is also the definition that I learned back during my computer science studies, but now that I search the Internet, I find that this definition is much less common, by a far stretch.

Under this definition:

  • The pepper is different for all users (like a salt).
  • It is not stored at all. After initially computing the password hash, you just throw it away and forget about it (unlike a salt).

Now when a user logs in, the server has to compute 28 hashes (one for each possible pepper) and see if one of them matches the stored password hash. If a single password hash can be computed in milliseconds or less, computing 28 hashes is not a problem. For an attacker who performs a brute-force offline attack though, this is a problem, because instead of having to compute 1 hash per possible password, she has to compute 256 hashes per possible password. So where the attacker may need 1 day without pepper, she will need 256 days with pepper.

I am not claiming this second kind of pepper yields a better improvement to security than the first kind. The problem I see here is that you can't well use a slow hash function since then the normal login process will take too long, and you can't use a fast hash function since then the attacker will have a much better chance of brute-forcing your hashes. It may be possible to find a compromise, but it is unclear whether this significantly increases security.

Question: Are there any canonical references that define what a pepper is? Like papers or books? Is the second definition ever used in practice? How did it come to be that there are two radically different definitions? Even though the first one seems to be the "typical" definition... come on... I learned the second definition back when I studied. It can't have been completely out of the blue. :)

Edit: References

Thanks to the answerers for providing enlightening explanations. I have summarized their references to various definitions of pepper from the literature here:

  • Udi Manber. A simple scheme to make passwords based on one-way functions much harder to crack. Computers & Security, 15(2):171–176, 1996.

    We deploy two salts, one public and one secret. The public salt is exactly the same as the current one. The secret salt is similar with one major difference: Like the password, but unlike the public salt, the secret salt is discarded by the system after use. It is not kept anywhere. (Unlike the password, it is not even kept by the user who does not need to know anything about it.) Like the public salt, the secret salt is generated at random at the time the password is first entered.

  • Gershon Kedem and Yuriko Ishihara. Brute force attack on UNIX passwords with SIMD computer. In Proceedings of the 8th USENIX Security Symposium. USENIX Association, 1999.

    The main idea is to add random bits to the password encryption, similar to the "salt" bits that are currently used to protect passwords against dictionary attacks. We call the new bits: "pepper" bits. Unlike the "salt" bits that are saved with the encrypted password, the pepper bits are used to encrypt the password, but are never saved.

  • Magnus Nystroem. The EAP protected one-time password protocol (EAP-POTP). RFC 4793, RFC Editor, February 2007.

    One way [to slow down an attacker] is for the client to include a value ("pepper") unknown to the attacker in the hash computation. (...) Since the pepper can be seen as a MAC key, its lifetime should be limited. (...) "pepper" is an optional nonce (...) included to complicate the task (...) for an attacker.

  • Christian Forler, Stefan Lucks, and Jakob Wenzel. Catena: A memory-consuming password-scrambling framework. Cryptology ePrint Archive, Report 2013/525, August 2013.

    One [way to thwart adversaries] is to keep $p$ bits of the salt secret, turning them into pepper [Manber96]. Both adversaries and legitimate users have to try out all $2^p$ values the pepper can have (or $2^{p-1}$ on the average).

  • $\begingroup$ I guess that the definition of a pepper is something that you put into a password hash function other than the salt and password. Basically I never heard of option #2, and I'm fully prepared to dismiss this idiotic idea and wipe it from memory again. If you use a "good" PBKDF function (PBKDF2, bcrypt, scrypt) it should already provide a non-random work factor (cost, iteration count), so you don't need a random pepper for that. Casino's may like the odds though :P $\endgroup$
    – Maarten Bodewes
    Commented Dec 1, 2014 at 22:35
  • $\begingroup$ The short of it is that there is no widely-agreed upon use of the word "pepper" when it comes to cryptography. $\endgroup$ Commented Dec 2, 2014 at 4:44
  • $\begingroup$ I don't understand the version when the pepper is not stored at all: if a pepper is used as part of the input for the hash, but then thrown away, what could be the use of the hash when it cannot be reproduced any more? $\endgroup$
    – not2savvy
    Commented Mar 29, 2023 at 14:13

2 Answers 2


My understanding of the term 'pepper' is that it more matches your definition 2, in that a pepper is an unknown salt, which makes it a cryptographic secret, but not a key. However, in use it is not as limited by either of your definitions:

  • The pepper can be different (or random) for all users (like a salt).
  • The pepper can be the same for all users (like a salt prefix).
  • The pepper is generally not stored with the salt.
  • The pepper is always known during hash creation, but may be unknown during verification.

The purpose of the pepper will vary depending on the type of algorithm, but the general definition is the same, "an additional input to the algorithm that is kept secret".

In Catena, the purpose of the pepper is to force a time parameter on verification, a 3-bit pepper will take up to 8 times longer to verify. This is mainly used to tune verification to multicore processors, so that they cannot be used to bruteforce the results as efficiently. This definition was first used in 1999 (as far as I can tell) when describing mitigation techniques to brute force attacks on the 'crypt' function used in UNIX systems. This matches your definition 2.

RFC 4793 defines the pepper as a value transferred over an encrypted handshake used to reduce the iteration count of PBKDF2 while still maintaining the same security. Once it is decrypted, it is appended to the salt. They describe it as both an "optional nonce" and a "MAC key", but their formal definition is "a value unknown to the attacker in the hash computation", that is not the one-time password. It is stored on the client device and server, and replaced whenever necessary, depending on length and security requirements.

Several systems use the pepper as a salt prefix or suffix. It differs per system using the algorithm, so that an identical combination of salt and password results in a different hash. In the implementations I have seen the pepper is not stored in the database, but rather in a configuration file used by the algorithm, or compiled into the program itself. In this case, admin access to the database has no access to the pepper, making it secret to the database, but not secret to someone with filesystem access. I use the term "server salt prefix" instead of pepper for this use. This is pretty close to your definition 1.

Some algorithms have been modified to add a value by appending it to the password. In this case the algorithm usually has some preset limit on password length, and this favors password entropy, as long passwords may truncate the value. I have also seen the output of a hash function hashed again, using the value as the new salt. In several cases this value has been called 'pepper' when describing the modification.

I have seen pepper defined as both known and unknown to the program, but assumed as unknown to an attacker. I have seen pepper defined as both a prefix to another algorithm input, as well as a unique input. I have never seen pepper strictly defined as any sort of cryptographic key material. Whatever the purpose, there does not seem to be a clear definition above "an additional input to the algorithm that is kept secret". How that input is added and how it is kept secret (and from what) varies too much for a stricter definition (in my opinion).

  • $\begingroup$ Thanks, this is a great answer. I agree with your more general definition of a pepper, which makes perfect sense. $\endgroup$ Commented Dec 2, 2014 at 21:32
  • $\begingroup$ Using an "unknown salt" to defend against multicore machines doesn't seem to be a helpful strategy – the attacker can still use all of his cores to brute-force, using different salts. (And also the actual verifier needs to guess the correct salt.) $\endgroup$ Commented Jul 24, 2016 at 15:25
  • $\begingroup$ @PaŭloEbermann the actual verifier sets the size of the pepper so they can utilize all cores in parallel, taking the same time as if they only had 1 core and no pepper. If the verifier has 8 cores and the attacker has 80, a brute force attack will take only 1/10 the time, instead of 1/80th the time $\endgroup$ Commented Jul 25, 2016 at 19:54

From the Catena paper, version 2.

A salt refers to an additional random input value for the password scrambler, stored together with the password hash. It enables a password scrambler to derive lots of different password hashes from a single password like an initialization vector enables an encryption scheme to derive lots of different ciphertexts from a single plaintext. Since the salt must be chosen uniformly at random, it is most likely that different users have different salts. Thus, it hinders against attacks where password hashes from many different users are known to the adversary, e.g., against the usage of rainbow tables [40].

Note that there are further ways to thwart adversaries, i.e., ways to perform key stretching. One is to keep p bits of the salt secret, turning them into pepper [34]. Both adversaries and legitimate users have to try out all $2^p$ values the pepper can have (or $2^{p−1}$ on the average). Note that a careless implementation of this approach could leak a few bits of the pepper via timing information, when trying out all possible values in a specific order. Thus, a better approach would be to start at a random value and wrap around at $2^p$. Kelsey et al. [28] analyzed another key stretching approach where a cryptographic operation is iterated $n$ times, where $n$ is secret. Boyen proposed in [9] a user-defined implicit choice for $n$ by iterating until the user presses a “halt” button.

Note that Catena also introduces the concept of a "garlic", a value to tune the memory consumption of the hash function. This is not a widely used standard.

  • $\begingroup$ Thanks, this is a good reference. (Btw, your link seems to point to a different version of the paper, which does not include your quote. The ePrint version does include that quote.) Another good reference is that [34] reference in the quote, which is a paper by Udi Manber, the current vice president of engineering at YouTube. I have summarized these (and the other answerer's) references at the end of my question. $\endgroup$ Commented Dec 2, 2014 at 21:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.