Following on from my earlier question Do I enhance security by appending all passwords with a fixed long string? I believe I can use PHP password_hash function with bcrypt on my server.

Two questions...

Do I hash the user so that I can search for the user with a fixed string in the database, then compare the password_hash() stored value with password_verify() and client hash pass ?

Do I have any advantage to hashing the password, or do I just send it unaltered over the HTTPS wire? I read elsewhere that this is fine but it leaves me unsettled.

  • Long time since I used PHP in anger so I can't answer that. What I can say is that you should NEVER store or communicate a password. You should only store the hash and only ever compare the hashes. Sep 18 '16 at 19:17
  • Sending a password or sending an unsalted hash over the wire is pretty much the same thing (the hash would in effect becomes the password). PHP password_hash() enhances security if someone gets a physical copy of the server DB - this extra layer would not be available if one just stored the hash.
    – fiprojects
    Sep 18 '16 at 19:26
  • A hash is non-reversable by definition so it isn't the same as the password. But that is why you add a "salt" to it at the server so that an attacker cannot use rainbow tables to crack the password db. The hash cannot be the same as the password as long as you are always hashing any password input from the user. Sep 18 '16 at 19:33
  • Exactly. But you are talking about PHP and so one assumes doing the hash on the server not the client. Hashing on the client serves no purpose. That is the one instance where you DO send the password and is why you must always use HTTPS on login pages and forms. Sep 18 '16 at 19:45

I have resolved - this is the process I am following in case anyone is interested.

During initial registration, user enters a login and password. Both are hashed, sent over HTTPS to the server.

Server DB saves the client login hash and the output to password_hash($pass,PASSWORD_BCRYPT, ["cost"=>12]) to the db.

Later, during login process, user enters login and password. Both are hashed, sent over HTTPS to the server.

Client requests server to search DB for the loginhash, retrieves the password_hash output.

if password_verify($clientpass, $dbpass) return true, then password is valid, else false/password invalid.

This works for me.

Why do I hash the user and the password on the client even though they go over the wire as https? Because fixed lengths are faster to search for in the DB (I mysql prepare all my queries to ensure not to depend on dirty client data). Also because even though the data goes encrypted, I prefer a long sequence of characters over the wire as opposed to a short sequence which a username/password might contain - in my world, it feels better though I believe from what I read I don't get if anything extra for the effort.

  • Wait, what. Do I understand that you hash on client side (this hash is effectively the "password" now), then store that plaintext in database. On login, you retrieve BCRYPT hash under plaintext index, and compare it. Shouldn't that just always return true (unless the index doesn't exist in database)?
    – domen
    Sep 19 '16 at 9:23
  • You need read the PHP page on password_hash() and password_verify(). The hash I make on the client is not stored in the database. The password_hash() function makes another hash - it is stored in the database (lets call it savedhash). Later, when login is attempted, the client sends the hash again, and using password_verify(), the client hash is checked against saved hash. The client hash and saved hash are not the same. password_verify tests to see if client hash can be computed to saved_hash. See php.net/manual/en/function.password-hash.php
    – fiprojects
    Sep 19 '16 at 11:16
  • This is not what you wrote though: "Server DB saves the client login hash and ..."
    – domen
    Sep 19 '16 at 13:40
  • 1
    Actually, you do get something from client-side hashing. An attacker that listens to the HTTPS traffic can see the packet lengths. But he cannot see which IP addresses use short passwords, since during transfer all passwords have the same length. Also, just in case the HTTP request is compressed, the compressed length is more immune to the actual password. Just imagine that the password might be the host name or part of it. Oct 16 '16 at 10:28
  • Paragraph 5 should start with "Server searches DB". Oct 16 '16 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.