Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

password_verify

 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have been following a tutorial to build a login page, I had it working fine using md5 to hash the passwords but now I'm trying to secure it a bit more using Bcrypt. It seems to be storing the hashed password in the database fine but when I compare them on login they don't match. Obviously I'm not comparing the same values but I'm at a loss as to how to fix this as I'm new to PHP. any help would be appreciated.



 
Sheriff
Posts: 21971
106
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're using password_verify incorrectly. I don't know what password_1 is there, but the result is not a password (hashed or otherwise), but a boolean that tells you whether or not the password (first argument) matches a hashed password (second argument).

What you need to do is:
  • Select the user without filtering on the password. Make sure the password hash is in the result set.
  • Call password_verify with the user-provided password and the password hash from the database.
  • Fail if the result is not true.
  •  
    Saloon Keeper
    Posts: 22246
    151
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Rob Spoor wrote:You're using password_verify incorrectly. I don't know what password_1 is there, but the result is not a password (hashed or otherwise), but a boolean that tells you whether or not the password (first argument) matches a hashed password (second argument).



    And that's actually recommended practice. There is no need to actually retrieve a password from a database to determine if it matches what the user entered. And in fact, it's less secure. Because now you'd have a known good password in memory and a hacker could then pluck it out and abuse it. Doing it by a match query means that at best the invader would have to keep making queries until a result responded true.
     
    Rob Spoor
    Sheriff
    Posts: 21971
    106
    Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'm not sure that I read your comment correctly, but with PHP's password_verify, you need to extract the password hash from the database. Not the password itself, that should never be stored anywhere. You can't let the database perform the match for you.
     
    Tim Holloway
    Saloon Keeper
    Posts: 22246
    151
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    As I read it, the password_verify function is more useful (and safer!) when used on system-local passwords. For example, on a Linux system, you could probably employ it to check a password against a hashed one in an .htpasswd file or /etc/shadow.

    As I said before, it's much safer to check database passwords like this:

    Your SQL may vary depending on database. The returned count is 0 for failure, 1 for success and 2 for a messed up user table (duplicate user entries).
     
    Johnny Quinn
    Greenhorn
    Posts: 22
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Rob Spoor wrote:You're using password_verify incorrectly. I don't know what password_1 is there,



    I should have included this piece of code. Im using password_1 and password_2 to check the passwords match. I will try and do what you recommend if I can.

     
    Johnny Quinn
    Greenhorn
    Posts: 22
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for all the tips, I will have to think about this for a while and try and get it working if not I will be back to you
     
    Johnny Quinn
    Greenhorn
    Posts: 22
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Rob Spoor wrote: I don't know what password_1 is there, but the result is not a password (hashed or otherwise), but a boolean that tells you whether or not the password (first argument) matches a hashed password (second argument).



    Is password_1 not my hashed password ?
    Whatever I'm doing its hashing the password to the database anyway.
     
    Rob Spoor
    Sheriff
    Posts: 21971
    106
    Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tim Holloway wrote:As I said before, it's much safer to check database passwords like this:

    Your SQL may vary depending on database. The returned count is 0 for failure, 1 for success and 2 for a messed up user table (duplicate user entries).


    Using the database's password hashing is safer, but you need to use it for both verification and storing. Unless the password hashing algorithm is well-known and standard, it will make your application less portable; you may not be able to switch from one database system to a different one without having to reset every password.

    Johnny Quinn wrote:


    No no no no no! Don't do that, ever! It's unsafe for two reasons:
  • Apparently, you can get the password to verify against in plain text. That's the biggest security no-no there is. Passwords should not be plain text, and it should not be possible to convert it back to plain text. That means that encrypting is also a no-no; although it's better than plain text, it's still possible to get the original password back, and you want to prevent that.
  • It allows for timing attacks. If you want to compare two strings that contain sensitive data like passwords or secrets, and you can't use password_verify for some reason, you should at least use hash_equals.

  •  
    Rob Spoor
    Sheriff
    Posts: 21971
    106
    Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Johnny Quinn wrote:Is password_1 not my hashed password ?


    I don't know. I see two code snippets. In the first, password_1 is the argument to password_hash which means it's the password to hash - the plain text password. In the second, which can't be used on the same page as the first, it just appears out of nowhere.
     
    Johnny Quinn
    Greenhorn
    Posts: 22
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Rob Spoor wrote:

    Tim Holloway wrote:As I said before, it's much safer to check database passwords like this:

    Rob Spoor wrote:
    No no no no no! Don't do that, ever! It's unsafe



    Of course, that makes sense, I have decided to try a different approach, using Okta to add authentication. Am I correct in thinking this will simplify things for me?

     
    Tim Holloway
    Saloon Keeper
    Posts: 22246
    151
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Rob Spoor wrote:
    Using the database's password hashing is safer, but you need to use it for both verification and storing. Unless the password hashing algorithm is well-known and standard, it will make your application less portable; you may not be able to switch from one database system to a different one without having to reset every password.



    I'm a very big proponent of not letting the end-user application also be the application that sets/changes passwords. I prefer delegating that to a secondary app where the security management isn't mashed in with general app code and therefore you can use separate database security contexts (userids) to handle the two different tasks. A multi-user application has to access the database with the greatest common denominator of all of the access needs of its users, so fencing off the sensitive stuff has to be done by outsourcing.

    That said, DBMS's that support encryption as a column function, all the major ones can just as easily use their encryption function in a SQL INSERT/UPDATE as in the WHERE clause of a select.

    I did a quick check of the major DBMS's. As a general rule, MD5 and SHA256 are well-supported. IBM's DB2 has its own process and it's based on MD5, but I'm not sure if that includes the end results. Everyone else is more straight-forward. And for the most part, if a DBMS doesn't natively include your encryption scheme of choice, it can usually be added as a user-defined function.

    Not to downplay the potential hit, but in my experience, changing databases is likely to introduce so many other portability concerns that resetting everyone's password is likely to be a minor issue.

    I need to check my more paranoid databases. It occurs to me that there are 2 levels of fetch security you might apply to passwords. One would be to permit or forbid actual retrieval of a field's value but permit it to be used in comparison (WHERE) clauses. The other would forbid comparison as well.
     
      Bookmark Topic Watch Topic
    • New Topic