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
show 2 more comments

5 Answers

up vote 45 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
8  
-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
show 3 more comments

In some circumstances, peppers can be helpful. (This answer is marked Community Wiki. Feel free to edit.)

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 = SHA512( $salt . $password )

where $salt is stored in plaintext in the database, together with the $hashed_password representation.

(I'm just using SHA512 as an example, assume that a few interations of any crossplatform cryptographic hash might have been used, i.e. MD5, SHA-family, etc. Actually, as noted below, a computationally expensive solution should be preferred.)

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 = SHA512( $salt . $pepper . $password )

where $salt is stored in plaintext in the database, and $pepper is a constant stored in plaintext in the application code.

Adding this $pepper is easy -- you're just creating a constant in your code, entering a large random value into it, and using that constant in the password hashing function. If you have existing users you need a migration strategy, but this is relatively easy because regardless of which hash function you use, you can add a hash with the pepper at the end.

Answer:

Using the $pepper does add to the strength of the password hash when compromise of the database does not imply compromise of the application.

But whether or not adding a $pepper is appropriate for your situation, you should always be sure that your cryptographic hash isn't too efficient and use e.g. scrypt or bcrypt.

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. –  Foo_Chow Feb 11 at 18:20
add comment

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
add comment

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
add comment

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
add comment

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.