4 ms·
ircmaxell makes a good point in that comment -- not that the concept of a pepper doesn't work, but that a two-way encryption function is a better choice than a
by JackC 12y ago
ircmaxell makes a good point in that comment -- not that the concept of a pepper doesn't work, but that a two-way encryption function is a better choice than a hash function for applying the pepper.
Your pepper will be a long, random key that is known to your app server but not your database server. If you store passwords as:
bcrypt(bcrypt(password, salt), pepper)
then you spend a lot of cycles bcrypting your long, random key, which is pointless (it should already be long enough to be un-brute-forceable), and you lose the ability to rotate keys or ever stop using this scheme in the future. There's also (in theory) some risk that nested bcrypt() doesn't work predictably.
If you store passwords instead as:
encrypt(bcrypt(password, salt), pepper)
then you can routinely rotate peppers through a simple one-time decrypt-and-encrypt step on your app server, instead of endlessly nesting peppers as suggested in the filippo.io blog post.
The rest of it is more of a qualitative question -- what's the risk that someone gains access to your DB but not your app server, vs. the risk that in implementing the pepper, you somehow screw up and store something easily crackable?
- eridius 12y ago> what's the risk that someone gains access to your DB but not your app server, vs. the risk that in implementing the pepper, you somehow screw up and store something easily crackable? The question is irrelevant anyway, because if someone gets access to your app server, they get the secret in both cases (pepper and encryption). So the first risk there is present in both cases, which just makes this a static "what's the risk that you screw up in implementing the pepper?"
- worklogin 12y agoThe question is not irrelevant. It's blindingly obvious that salt+pepper protects against DB-only attacks. Injection that does a DB dump, or vulnerabilities in the DB server that don't exist in the app. So yes, S+P protection won't save you if the app server is completely compromised, but it does protect you in case DB only is. And the ability to S+P seems pretty simple to implement and document. Why is everyone panicking that it's hard to do?
- eridius 12y agoI read your question as comparing the originally-proposed pepper approach vs the encryption approach, and I said the question was irrelevant because both approaches have the identical risk that the app server is compromised, but only the originally-proposed pepper approach has the risk that it's not actually secure (e.g. because naïvely composing hash operations may be bad, and adding static bits to passwords may also be bad). But upon reflection I believe you were instead using the term "pepper" to include the encryption approach as well and merely trying to question whether the added security of requiring an app server compromise is worth the risk that you still screw it up somehow. And to that I'd say that it's not difficult to apply an existing block cipher algorithm when storing/retrieving password hashes so I think the risk there is low. > Why is everyone panicking that it's hard to do? Everybody's panicking because the originally proposed pepper implementation is a really bad idea. That approach has not been researched for security implications, and there are many reasons to believe that composing hash operations without using a specially-defined operation like HMAC is bad, and adding static bits to the salt or password (e.g. if you use 'pepper.salt' for the scrypt salt or 'pepper.password' for the password) is also bad. However, I believe the approach of using a block cipher to encrypt your hashes with an app-wide password is reasonable. It's not composing operations badly (encrypting a 256-bit string, or whatever scrypt emits, is perfectly reasonable given a secure key) or otherwise providing an attack vector on the hash algorithm. The biggest risk I can see with this approach is you have to make sure the pepper is stored securely on your app server, never visible to the database server (and never accidentally committed to an open-source repo, if you're using an open-source server). Not just that, but you have to make sure that you don't accidentally lose it either (or you'll have instantly lost all your accounts). But this is a solvable problem.
- mirashii 12y agoBecause it's harder to implement and easier to mess up than using standard encryption, and has unknown characteristics due to the fact that it's rolling your own crypto. Why would you spend the time and effort to implement it when you can do something that is objectively better in every way?
- mbrubeck 12y agoI've already seen one person in this thread taking "S+P" literally, and suggesting `bcrypt(cost, salt + pepper, password)`, which has a very obvious and critical problem. Other "peppering" schemes in the comments here also have significant weaknesses. So yes, even a simple idea like this is easy to botch in implementation -- even if the implementation is just a one-line change!
- docbrain 12y agoYou never know. Some developers might not be smart enough to use an SSL connection from their app server to their DB server. The influx of newb devs out there is growing and security is usually not high on the learning list or the new devs priority list. If so, hackers could possibly get access to the DB without even needing the app server in the first place. Get your certs folks!
- eridius 12y agoI don't see how this is relevant. There is no reason to believe that the hacker needs to get at your app server in order to access your DB server in the first place.
- rnovak 12y agoOnce you use Encryption, it's no longer pepper, it's encryption with weak key storage (hard-coded). At that point, genuinely, why not just follow best practices and store the key securely (e.g. using an HSM)?
- Someone1234 12y agoBecause nobody knows how to do that and it is likely extremely expensive by every metric. And, no, I am not being facetious by saying nobody knows how to do that. I am being quite literal. Have you ever done that? Do you know how? Do you even know what you would google to figure out how? I'm yet to see my favorite library of course's documentation on a HSM. How do you do that in e.g. PHP with MySQL? MVC with MS SQL? Java with Oracle?
- rnovak 12y agoIt's worth it. And yes, I have done that, it's not a mystery, they all provide a API/ABI for interacting with them[1], such as OpenSSL's Engine API or PCKS#11. Edit: There's even a project to literally do this directly from PHP[3] [1] http://stackoverflow.com/questions/10796485/interfacing-with-a-hardware-security-module-on-linux http://stackoverflow.com/questions/10796485/interfacing-with... [2] http://en.wikipedia.org/wiki/PKCS_11 http://en.wikipedia.org/wiki/PKCS_11 [3] http://stackoverflow.com/questions/3231293/how-to-interface-with-pkcs11-compliant-hsm-device-in-php http://stackoverflow.com/questions/3231293/how-to-interface-...
- MichaelGG 12y agoEh, I had a Luna CA3 sitting on my desk for a while. HSMs aren't that exotic. I'd be more concerned about the HA aspects which could require extra code. I suppose you could just shove a USB HSM in several of your servers and encrypt every password with at least 2 of them.
- Zombieball 12y agoI think AWS provides both key management services as well as cloud hsm. I have not used either myself, but I would imagine the documentation is quite good.