5

I came about this security discussion after reading some topics about session management in php, have a look: https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title.2

Quote from Chapter: To Pepper Or Not To Pepper?

A much better solution, which is especially useful if you employ hardware separation, is to encrypt the hashes before you insert them in your database. With this safeguard in place, even if an attacker finds a way to dump all of your database tables, they first have to decrypt the hashes before they can even begin to crack them. With the PHP and the database on separate hardware, this becomes much more secure.

In this article, the link to https://github.com/defuse/php-encryption is shared...

So far, I only used password_hash() in order to store passwords in a database. Is it recommendable to encrypt the hash itself? What's your opinion?

Thanks for your ideas!

1615903
  • 32,635
  • 12
  • 70
  • 99
Chris
  • 111
  • 8
  • 1
    I'm not sure but wouldn't this be more suited to http://security.stackexchange.com/ ? – Pogrindis Jan 21 '16 at 12:09
  • 1
    The security of hashes comes from the fact that it takes too long to guess the plaintext value. The security of encryption comes from the fact that it takes too long to guess the key. In both cases, the security simply stems from the fact that it's computationally infeasible to guess all possible keys. With properly implemented hashing, that should already be infeasible enough. Upping the ante even more is certainly not bad, but whether it's worth the additional complexity is up to you. – deceze Jan 21 '16 at 12:16
  • You are mixing up encryption and encoding in your question - this question is about encryption. – 1615903 Jan 22 '16 at 09:48

3 Answers3

6

Hashing with an appropriate hash algorithm is usually enough to protect the passwords, but it is indeed more secure to encrypt (not encode) the hashes afterwards.

When you encrypt the hashes with a server-side key, an attacker must gain additional privileges on the server, to get this key (without the key, the hashes are worthless). It is much easier to get readonly access to a database, than to get privileges on a server. Examples are SQL-injection, thrown away backups, discarded servers, ... In all this cases the encryption would protect the hashes.

In this answer you can find more information, or maybe you want to have a look at the end of my tutorial about safely storing passwords.

Community
  • 1
  • 1
martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
  • Concise and unassuming! Great answer. – Pogrindis Jan 21 '16 at 12:09
  • I'm one of the authors of the article they cited. I probably should have emphasized "this only improves security when the database is on separate bare metal". – Scott Arciszewski Jan 21 '16 at 18:54
  • @ScottArciszewski - Often the web server and the database server _are_ on different machines especially in shared hosting. I know in discussions the argument "if an attacker can brake in the database, he can likely read the file system too" is very popular, but those are really two pairs of shoes. Taking over a server needs much more knowledge and luck, than tricking an application to reveal a bit too much of infos. I appreciate that you mentioned the usage of a server-side key in your article. – martinstoeckli Jan 21 '16 at 21:52
  • In the pentests I've conducted where I actually found a useful SQL injection vector, I successfully got a PHP shell out of it every time, which in turn allowed me to read config files directly. `SELECT 'arbitrary' INTO OUTFILE '/var/www/publicly_accessible'` is pretty useful ;) – Scott Arciszewski Jan 22 '16 at 00:12
  • @ScottArciszewski - The providers i where in contact with, all prevent the usage of LOAD_FILE() or INTO OUTFILE(), and without those it is difficult to attack the server itself (or do i miss something?). That's why i assumed, this is a standard security measure. Please correct me if i am wrong. – martinstoeckli Jan 22 '16 at 09:55
  • Yep, that makes it more difficult without exploiting the RDBMS itself. (I wouldn't rule that out either, however.) – Scott Arciszewski Jan 22 '16 at 15:50
  • Thanks for your answers. Both of you gave precise and clear informations, thanks! :) – Chris Jan 23 '16 at 22:45
2

Is it recommendable to encode the hash itself? What's your opinion?

No, password_hash() / password_verify() is sufficient. People who need spinal-tap grade security can refer to that part of the article for guidance to avoid accidentally shooting themselves in the foot trying to improve their security, but in general if you're using bcrypt in 2016 then you're fine.

Unless you have separate servers for your website and for your database, the security gain by this strategy is zero. If I can get into your database, I can almost certainly get to your file system, and recover the encryption key.

If you do have separate hardware, and you use an authenticated encryption library such as the one provided by Defuse Security, do feel free to use it. Just know that it's not necessary for most use cases, as the password hashing API provides decent security against modern password cracking.

In a later version on PHP, they'll also support Argon2. If you're going to go overboard, switch to that instead of adding complexity to your protocol.

(Also, it's encrypt, not encode.)

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
0

there's no need at all to encrypt the hashes. The attacker has to reverse the hash to find the correct plaintext (user password). This is equivalent to find out the right key for the encryption. hashing is enough. plus salt obviously otherwise your schema is susceptible to rainbow table attacks

Gianluca Ghettini
  • 11,129
  • 19
  • 93
  • 159
  • "The attacker has to reverse the hash to find the correct plaintext (user password)." Yes, and they can't even begin to use their distributed password cracking clusters if they don't even have hashes to work with. – Scott Arciszewski Jan 23 '16 at 22:59
  • Why? Do you really want me to debunk your "This is equivalent to find out the right key for the encryption" notion with math? – Scott Arciszewski Jan 24 '16 at 00:26
  • @ScottArciszewski nothing to debunk. An encryption layer on top of hashing doesn't improve security *at all*. Just use widely used standards like bcrypt or PBKDF2 which adds salt and a work load and you are done. Don't go DIY on this things otherwise you are going to shoot yourself in the foot (in most cases going DIY actually LOWERS the security level of an application). – Gianluca Ghettini Jan 27 '16 at 12:00
  • "An encryption layer on top of hashing doesn't improve security at all." Nah, I meant the security margins of each, considered separately, isn't equivalent :P. I've also outlined a specific corner case where hash-then-encrypt can improve security. "(in most cases going DIY actually LOWERS the security level of an application)" Agreed 100% – Scott Arciszewski Jan 27 '16 at 18:43