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.

For hashing passwords in a database, i would like to add a pepper to the hash function. Of course this pepper will be additionally to the unique salt.

The reason why i want to add a pepper is, that it prevents a dictionary attack, in case that the attacker has only access to the database, but not to the server (typical for Sql-Injection). In my opinion this is better than a hash without pepper, even if the pepper is only hardcoded (to avoid code complexity).

Now i wonder, how the pepper should be applied correctly, is it correct to just append the pepper to the password before hashing?

1. Concatenating password and pepper

$passwordHash = bcrypt($password . $pepper, $salt);

A reason against this could be, that passwords bigger than the bcrypt limit (55 characters) will not get the pepper, although passwords of this length are propably not in a dictionary anyway. Because of this limit, the pepper is added after the password and not before. Another reason could be, that if the attacker knows the pepper, he also knows the ending of all our peppered passwords.

2. Combine password and pepper with hash

$passwordHash = bcrypt(hash('sha256', $password . $pepper), $salt);

So we could use a hash function to combine password and pepper, before hashing. Is it appropriate to use sha256, or which hash function would be ideal, when we want to use bcrypt afterwards?

3. Combine password and pepper with hmac

$passwordHash = bcrypt(hash_hmac('sha256', $password, $pepper), $salt);

Often a hmac is the recommended solution, is there any advantage over using SHA256 directly? Since we only want to combine password and pepper, and the security comes later from the bcrypt, i cannot see any apparent advantage.

Any helpful hints are much appreciated.

share|improve this question
    
Isn't hash_hmac('sha256', $pepper, $password) will be more correct (use $pepper as HMAC's key)? –  Powerman 3 hours ago
    
Is there any difference for security between bcrypt(hmac($pepper, $password), $salt) and hmac($pepper, bcrypt($password, $salt))? –  Powerman 3 hours ago
add comment

1 Answer

up vote 8 down vote accepted

Your three methods are correct. The third (with HMAC) might be a tad more "elegant", mathematically speaking: it would make it easier to prove the security of the construction, relatively to those of bcrypt and HMAC.

Beware, though, of null bytes. A given bcrypt implementation might expect a character string and stop at the first byte of value 0, which may occur in the output of either SHA-256 or HMAC (or as part of the binary key you use as pepper), ignoring all subsequent bytes. It would be a grave problem, and you would not notice it. To avoid that problem, you might want to Base64-encode the SHA-256 or HMAC output before giving it to bcrypt (Base64-encoded SHA-256 output is 44 characters, still below the bcrypt limit).

share|improve this answer
    
Thanks a lot for this helpful answer, especially the tip about binary output. So you see no obvious problems with just concatenating password and pepper? –  martinstoeckli Oct 7 '12 at 21:10
    
As long as the pepper is of fixed size (so that it could be unambiguously "removed"), and you do not exceed the 55-character limit, and avoid the troublesome zeros, then concatenation should be fine. –  Thomas Pornin Oct 7 '12 at 21:13
    
Given that BCrypt doesn't actually have a "pepper" input, isn't it potentially safer to either encrypt or HMAC the password digest? Peppers feel very much to me like inventing your own crypto. –  Stephen Touset Oct 7 '12 at 21:14
1  
bcrypt is meant to tolerate passwords as input. Passwords are about the worst kind of input you can get; I do not see harm coming that way, when adding a MAC. The danger here would be that the addition of the "pepper" induces two distinct passwords to yield the same bcrypt input, e.g. because of an unwanted truncation from a null byte. Apart from that, anything which looks like an injection can be applied to the input of bcrypt as a preparation step (hashing or MACing is injective-like because finding collisions is hard). –  Thomas Pornin Oct 7 '12 at 21:20
    
What about applying an HMAC or encrypting the output? Although with standard BCrypt libraries, an HMAC might be annoying since they don't typically provide explicit access to the salt and cost factor in the input or output. –  Stephen Touset Oct 7 '12 at 21:28
show 1 more 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.