Jonathan, On Tue, Jul 31, 2012 at 12:01 PM, Jonathan Bond-Caron <jbo...@openmv.com>wrote:
> On Tue Jul 31 10:54 AM, Anthony Ferrara wrote: > > > > On Tue, Jul 31, 2012 at 10:28 AM, Jonathan Bond-Caron <HYPERLINK > > > > I strongly disagree with this, the 'pepper' IMHO is a best practice > > for web applications. > > > > Again, I have not seen this being said by any security or cryptography > > expert. > > > > Like I said IMHO, I'm not a security expect but I do think there needs to > be > modern discussion around 'web password hashing'. I'm not against discussion. I'm against core implementations (or recommendation) of non-vetted cryptographic processes... > > > > Ok. So I register an account before I get the database. Now the only > thing > that I need to crack is the pepper (since I know the salt, hash and > original > password for my sentinel account). > > Fair enough ;) > > It can still be a problem if the pepper is large + the crypt() salt > > > > With all of that said, if you really want a secret in there, don't > > hijack the hashing algorithm to do it. There are two somewhat decent > > alternatives: > > > > HMAC the password with the secret prior to passing it to > > password_hash()/crypt(). HMAC is secure and is designed for this > > exact purpose. > > > > Not so great: > password_hash_rfc( hash_hmac('md5', 'password', '1024-bytes secret') ) // > hmac is short (~ 160bits) > In that case, the HMAC would produce exactly 128 bits of output. Why would you use MD5 for that? Use SHA512. That gives you (in your case) a 128 character password (or 64 if you pass true to the third parameter, which you should). Also, be aware that BCrypt only uses the first 72 characters of the password field. So if you use a hex encoded sha512 output, a good deal of entropy would be lost (almost half of it)... > I guess you mean: > > hash_hmac('md5', password_hash_rfc('password'), '1024-bytes secret') > > But then there's no way to know all those crypt() parameters, salt, cost, > etc... > Absolutely not. That would make the hash unverifiable... > Maybe a new api? > password_hash_hmac($password, $secret, $options = array()); Again, implementing something in the core that's not verified and can't be implemented well by the vast majority of developers out there. So a big -1 from me... > > > > Encrypt the resulting hash with a secure encryption function > > (RIJNDAEL_128 + CBC) prior to inserting it in the database. That way, > > each component uses standard algorithms as they were designed to be used. > > > > That's fine, I feel this should be somewhat easier in php core (without the > need for openssl & al.) > > It also comes with a cost of decrypting the hashes / not so great > Huh? How is that not great? The encryption is actually quite fast... And you actually want to slow down password hashing (to make it more difficult to brute force), so I fail to see how this is an issue... > > But I want to stress something else. Properly managing secrets is VERY > > difficult. It's not even really possible in PHP, due to the way > > copy-on-write works, and how variables are removed. To implement this > > sort of a system correctly is not something even highly competent > > developers can typically do. It really is that difficult to get right. > > > > Sure managing keys properly can be hard, simple cases: > $secret = MY_KEY; > $secret = file_get_contents('/security/key.pem'); > Actually, that's not properly managing the key. It requires the web server user to be able to read the key. That allows anyone who gains permissions as the web server (even on a different vhost) to be able to get your key. Properly managing it would require either a dedicated cryptography server to handle it for you, or a dedicated piece of hardware to manage the key. Anything less is just security through obscurity... > Again I'm making the assumption that the attacking *does not* have access > to > the file system. Actually, you need to make the reverse assumption. You want to make the data secure *even if* the attacker gets access to the filesystem. Now obviously if they inject code into the stack they'll be able to view the raw password from the user. But that requires long term access (and write access). But the data stored should be protected even if the filesystem is compromised...