Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Please Note: I'm aware that the proper method for secure password storage hashing is either scrypt or bcrypt. This question isn't for implementation in actual software, it's for my own understanding.

Related


Background
As far as I know, the recommended/approved method for storing password verifiers is to store:

$verifier = $salt + hash( $salt + $password )

Where
  hash() is a cryptographic hashing algorithm
  $salt is a a random, evenly distributed, high entropy value
  $password is the password entered by the user

Some people advice to add a secret key into the mix (sometimes called 'pepper'). Where the pepper is a secret, high entropy, system-specific constant.

The rationale seems to be that the it even if the attacker gets hold of the password verifiers, there is a good chance he or she does not know the pepper value. So mounting a successful attack becomes harder.

So, my question is:
Does adding a pepper value in addition to a salt when hashing passwords increase the overall security?

Or is the perceived increased security based on false assumptions?

Quick Update
I know the purpose of the $salt (I wrote quite a long answer on stackoverflow about it) the additional $pepper key is not  improving upon what the salt does.
The question is, does the $pepper add any security other than what the salt does.

share|improve this question
1  
You salt a hash to avoid them being cracked by a rainbow table. And then threes not really a lot of need to add an additional constant to the mix. –  KilledKenny Apr 22 '11 at 10:30
    
Related but not quite the same as security.stackexchange.com/questions/211/password-hashing –  AviD Apr 22 '11 at 13:17
    
Like @WzeberaFFS said, there's no extra cryptographic strentgh coming from 'publishing' your salt like that. I'm thinking thought you're asking about why do hashes in like /etc/passwd have a format of $1$saltsalt$realhashhereblahblah, is that right? If yes, then it's so the verifier can take the password, add the visible salt to it, then hash it. Without the salt being visible you could never recreate the hash. –  Marcin Apr 22 '11 at 13:19
4  
If I understand correctly, and this was discussed in the q I linked to, a pepper can "...help mitigate certain compromise scenarios (eg, database backups going missing) by having a piece of the puzzle stored elsewhere" (@RoryMccune). Also can differentiate your hashes from someone elses - IF a big enough rainbow table is ever constructed... –  AviD Apr 22 '11 at 14:15
2  
This question asks specifically about pepper. For the broader picture, see a more complete discussion elsewhere on IT Security StackExchange of the more general topic of password hashing –  nealmcb May 14 '11 at 19:23

6 Answers 6

up vote 50 down vote accepted

(Note: using a salt is only half of the job; you also need to make the hash function slow -- so that attacking a single low-entropy password is still difficult. Slowness is usually achieved through multiple iterations, or hashing the concatenation of 10000 copies of the salt and password.)

What your "pepper" does is that it transforms the hash into a MAC. Making a good, secure MAC out of a hash function is not easy, so you'd better use HMAC instead of a homemade construct (the theoretical way of putting it is that a collision-resistant hash function is not necessarily indistinguishable from a random oracle).

With a MAC, you may gain some security in the following sense: possibly, database read access by the attacker could cease to be a real problem. The MAC key (the "pepper") may concentrate the confidentiality need. However, this relies on the MAC being also a one-way function, which is a property which you will get from many MAC constructions (including HMAC) but which is not really guaranteed cryptographically speaking (there are subtleties).

The "pepper" implies that you have a key to manage, including secure storage in a way which resists to reboots. A key is small and fits in RAM, but, due to the storage requirements, it is unclear whether it actually improves security. An attacker who can read the whole database usually can also read the whole harddisk, including any "protected" file. The key small size may allow for some advanced setups, e.g. the key being stored on smartcards which are used at boot time but not left connected afterwards. To sum up, whether peppering is worth the effort thoroughly depends on the context -- on a general basis, I would recommend against it, in order to avoid the added complexity.

share|improve this answer
    
I'm trying to wrap my brain around "Adding a key the hash transforms it into a MAC". Am I correct in understanding that, by adding a constant value (along with the password and salt) into the hashing algorithm, the changed use of the primitive affect the stength of the outcome? And that, if the key is known, the overall scheme is likely to be less secure? –  Jacco Apr 22 '11 at 20:19
1  
@Jacco: if the hash function is any good, then no, you do not weaken it in any way by adding a known prefix or suffix. However, being a good hash function is not fully equivalent to being a good MAC (the difference is subtle but real), hence the need to follow well-studied constructions such as HMAC. As for a good book, you can try the Handbook of Applied Cryptography ( cacr.math.uwaterloo.ca/hac )(not the same book than "Applied Cryptography" by Schneier). –  Thomas Pornin Apr 22 '11 at 20:54
    
@Thomas Pornin: Please see my answer below -- I'm not sure if we are talking about the same thing. If we are, then I'm using words more common to webapp developers below, so your comment on what I'm describing would be valuable. –  Jesper Mortensen Apr 23 '11 at 8:40
4  
@Jesper: we are talking of the same thing, but with distinct viewpoints. The "pepper" increases security only insofar as it is not known by the attacker -- whether this is true or not is not easy to guess, especially in your setup in which the webapp and the database are on distinct machines. The pepper will not decrease security by itself, except that it increases installation complexity (a value which must not be known by the attacker is a key, and key management is known to be non-immediate). Also, with a secret pepper, security increase depends on whether the construct is a good MAC. –  Thomas Pornin Apr 23 '11 at 14:09
11  
-1 for the comment "An attacker who can read the whole database usually can also read the whole harddisk". Clearly you are not a penetration tester, don't make such assumptions. –  Rook Jul 19 '12 at 9:23

In some circumstances, peppers can be helpful.

As a typical example, let's say you're building a web application. It consists of webapp code (running in some webapp framework, ASP.NET MVC, Pyramid on Python, doesn't matter) and a SQL Database for storage. The webapp and SQL DB run on different physical servers.

The most common attack against the database is a successful SQL Injection Attack. This kind of attack does not necessarily gain access to your webapp code, because the webapp runs on a different server & user-ID.

You need to store passwords securely in the database, and come up with something on the form of:

$hashed_password = hash( $salt . $password )

where $salt is stored in plaintext in the database, together with the $hashed_password representation and randomly chosen for each new or changed password.

The most important aspect of every password hashing scheme is that hash is a slow cryptographically secure hash function, see http://security.stackexchange.com/a/31846/10727 for more background knowledge.

The question is then, given that it is almost zero effort to add a constant value to the application code, and that the application code will typically not be compromised during an SQL Injection Attack, is the following then substantially better than the above?

$hashed_password = hash( $pepper . $salt . $password )

where $salt is stored in plaintext in the database, and $pepper is a constant stored in plaintext in the application code (or configuration if the code is used on multiple servers or the source is public).

Adding this $pepper is easy -- you're just creating a constant in your code, entering a large cryptographically secure random value (for example 32byte from /dev/urandom hex or base64 encoded) into it, and using that constant in the password hashing function. If you have existing users you need a migration strategy, for example rehash the password on the next login and store a version number of the password hashing strategy alongside the hash.

Answer:

Using the $pepper does add to the strength of the password hash if compromise of the database does not imply compromise of the application. Without knowledge of the pepper the passwords remain completely secure. Because of the password specific salt you even can't find out if two passwords in the database are the same or not.

The reason is that hash($pepper . $salt . $password) effectively build a pseudo random function with $pepper as key and $salt.$password as input (for sane hash candidates like PBDKF2 with SHA*, bcrypt or scrypt). Two of the guarantees of a pseudo random function are that you cannot deduce the input from the output under a secret key and neither the output from the input without the knowledge of the key. This sounds a lot like the one-way property of hash functions, but the difference lies in the fact that with low entropy values like passwords you can effectively enumerate all possible values and compute the images under the public hash function and thus find the value whose image matches the pre-image. With a pseudo random function you cannot do so without the key (i.e. without the pepper) as you can't even compute the image of a single value without the key.

The important role of the $salt in this setting comes into play if you have access to the database over a prolonged time and you can still normally work with the application from the outside. Without the $salt you could set the password of an account you control to a known value $passwordKnown and compare the hash to the password of an unknown password $passwordSecret. As hash($pepper . $passwordKnown)==hash($pepper . $passwordSecret) if and only if $passwordKnown==$passwordSecret you can compare and unknown password against any chosen value (as a technicality I assume collision resistance of the hash function). But with the salt you get hash($pepper . $salt1 . $passwordKnown)==hash($pepper . $salt2 . $passwordSecret) if and only if $salt1 . $passwordKnown == $salt2 . $passwordSecret and as $salt1 and $salt2 were randomly chosen for $passwordKnown and respectively $passwordSecret the salts will never be the same (assuming large enough random values like 256bit) and you can thus no longer compare password against each other.

share|improve this answer
    
Hmm, the edit removed the much of the uncertainty present in the answer as written by @Jesper Mortensen. Maybe the edit should be rolled back and moved to a separate answer? –  Jacco Apr 23 '11 at 22:08
1  
The gist of the argument here is pretty good and I tend to agree. However don't put a constant in the code if you can avoid it, make it a configuration variable of some kind (obv. not stored in the DB, but not in the code either). –  frankodwyer Apr 24 '11 at 9:30
    
@Jacco: I agree that the tone of this answer has changed with the edits done. But then, looking at who made the edits, I'm now more comfortable that this answer is correct (within its scope), so I'm happy to leave it as it is now. :-) –  Jesper Mortensen Apr 24 '11 at 11:27
    
I agree with the statement: that it is almost zero effort to add a constant value. It really is, so albeit not as critical as salting a password, I see no reason to exclude peppering in some form to provide an application code level protection. –  foochow Feb 11 at 18:20

I would like to point out what a pepper really can do.

When does a pepper help?

As the others already pointed out, adding a pepper is only an advantage, as long as the attacker has access to the hash-values in the database, but has no control over the server, and therefore does not know the pepper. This is typical for SQL-injection, probably one of the more often used attacks, because it is so easy to do.

What does a pepper improve?

$hashValue = bcrypt('12345', $cost, $salt);

This password you can get easily with a dictionary attack, even if you correctly used a slow key-derivation function. Put the most used passwords into a dictionary and brute force with this weak passwords. It's very likely that we find the password in (too) many cases.

$hashValue = bcrypt('12345anm8e3M-83*2cQ1mlZaU', $cost, $salt);

With the pepper, the weak password grows in length, it contains now special characters, and more important, you will find it in no dictionary. So, as long as the pepper stays secret, it does prevent dictionary attacks, in this case it can protect weak passwords.

Edit:

Often it is recommended to combine password and pepper with a hmac. In both cases the pepper fulfills its job as long as it stays secret. When it becomes known, neither will give any advantage.

$pepperedPassword = hash_hmac('sha256', '12345', 'anm8e3M-83*2cQ1mlZaU');
$hashValue = bcrypt($pepperedPassword, $cost, $salt);

One should be careful, that the result of the hmac is not binary output, because a bcrypt implementation could stumble over a null byte in the peppered password.

share|improve this answer
    
I would suggest bcrypt(hash_mac('sha256', $password, $pepper), $salt) –  Jacco Nov 2 '12 at 16:06
    
@Jacco - Just added an example of using a hmac. –  martinstoeckli Nov 2 '12 at 21:42
    
I'm not sure in what language your example is, but it would be more clear if it where language agnostic –  Jacco Nov 5 '12 at 7:23
    
@Jacco - It is PHP, but the function bcrypt is fictitious, because PHP itself does not provide such a function yet (before 5.5), the function hash_hmac exists though. I tried to edit the answer, so all confusing parts are removed, what do you think i could improve more? –  martinstoeckli Nov 5 '12 at 8:00

The paper on the invention of salting and iterations, for Unix passwords (Password Security: A Case History, Morris & Thompson, 1978), also described the equivalent of a pepper:

The first eight characters of the user’s password are used as a key for the DES; then the algorithm is used to encrypt a constant. Although this constant is zero at the moment, it is easily accessible and can be made installation-dependent.

I haven't heard of it being used though. Has anyone else?

share|improve this answer
    
I think all modern distros use something based on a hash function (not an encryption function like DES), so this ability isn't available anymore. –  Brendan Long Nov 15 '12 at 18:16

Consider this scenario:

I am about to break into a website X using an SQL injection to retrieve a list of users, with their password hashes and salt. Suppose website X is also using a global pepper.

All I would have to do would be to register a user at website X with a user name and password known to me prior to the SQL injection. I would then know, for a particular record in the database, the password hash, the plain text password, the salt (stored as plain text) and it would be computationally trivial for me to crack the global pepper on the basis of this one record.

So really, a pepper would be a way of slowing an attacker down for a trivial amount of overhead time. They wouldn't have to brute force the password + salt + pepper, as intended, only the pepper.

share|improve this answer
3  
What if the pepper is a 128 bit random value? Is it still trivial to crack it on the basis of salt and plaintext password value? The reason why salt and pepper values are helpful is because you can easily make it long enough (128 bit) and you don't have to remember it that is why cracking it through brute force is never trivial. –  void_in Aug 31 '13 at 10:25

Not very familiar with how a server would be able to hide a global pepper constant but my take is that sooner or later a hacker that has penetrated the server will figure out how to capture the pepper value. To make a pepper value totally secure would require special hardware. One way to do this would be to use a FPGA board installed in the server. The FPGA would contain the code used to perform the hash including the pepper value and all hash calculations occur inside the FPGA. With the FPGA, the programming can be a one way function. The pepper can be programmed in but there is no instruction that can be sent to read it back out. The pepper would be stored on a piece of paper locked in a safe. If the pepper is 128+ bits generated randomly, there would be no practical way of determining it.
Not sure how practical this would be as it would increase server hardware cost.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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