#1
  1. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171

    Problem with CRYPT_BLOWFISH


    Hi;

    Not sure why it keeps saying: Match!

    It is not supposed to match.

    Thanks
    PHP Code:
    public function index()
            {
                
                
                if(
    $this->verify($this->generate_hash(2),32))
                    {
                        echo 
    "Match";
                    }
            }
        
        public function 
    generate_hash($password=NULL)
            {
                if (
    defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH)
                {
                    
    $salt '$2y$11$' substr(md5(uniqid(rand(), true)), 022);
                    return 
    crypt($password$salt);
                }
            }    
        public function 
    verify($password$hashedPassword)
            {
                return 
    crypt($password$hashedPassword) == $hashedPassword;
            } 
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Hi,

    do not use crypt() directly! I'm pretty sure I already told you this several times, but I'll repeat it as often as you want.

    Using crypt() properly is very difficult. Almost everybody gets it wrong, even the people who specialize in security.

    On a quick glance, I already see 6 massive errors on your part, one of the breaking the whole authentication mechanism. Isn't that a clear warning sign? What more do you need?

    Use a library, seriously. When you end up opening your admin account to everybody, the whole bcrypt magic is useless.

    I usually recommend password_compat, but it also has some issues currently, so I'll recommend PHPass instead. It's from the same person who wrote the original bcrypt implementation of PHP, and it's very mature.

    Cryptography isn't the right place for playing around. It's very different from, say, programming a web application, because you have no margin of error. Screwing up some GUI elements doesn't hurt anyone. Screwing up a password hash does.

    For the sake of completeness, those are the errors:

    • wrong randomness source, massively weakening the salt
    • wrong salt encoding, again weakening the salt
    • wrong last digit of salt
    • no error checking; you don't even make sure that the hashing actually worked
    • wrong comparison technique
    • wrong order of arguments

    Please note that I'm not suggesting to fix this. I'm suggesting to stop and use a library.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. #3
  5. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,294
    Rep Power
    9400
    I think I'll actually back up Jacques on this one. His vitriol aside, it does kinda look like you're not sure how to use the code, and the reason you're getting the result you are is because of (a) not using the code right and (b) sheer luck.

    Passing numbers around? That doesn't make sense: generate_hash() is supposed to take a password you hash (not a number), and the arguments to verify() are respectively the original password (not the hashed password) and the hashed password (not a number).
  6. #4
  7. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,908
    Rep Power
    6352
    CRYPT_BLOWFISH maybe isn't defined. In that situation, the function returns null regardless of input.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    The problem has been solved.

    For those who are interested in the bug itself, the problem is caused by a whole chain of errors:

    He has mixed up the arguments and passes the integer 32 to the salt parameter of crypt. This causes the function to apply the ancient DES-crypt algorithm with two digits of salt. Then he uses the weak equality operator on the hash and the number 32. Since the hash happens to begin with the two salt digits, converting it to an integer does in fact yield 32 -- so the comparison is true.

    Bugs like this are very common. I'd say that 95% of the people using crypt() directly in fact use it wrong. It's a very error-prone function with exotic requirements and weird behaviour:

    • Mistakes will lead to very different reactions, depending on what exactly went wrong. The function may fall back to a weak algorithm (MD5-crypt or DES-crypt), or it may return an invalid hash, or it may return one of the error strings "*0" or "*1".
    • The salt must be encoded with a special Base64 variant. Contrary to popular belief, you can't just take common Base64, remove the padding and replace "+" with ".". The crypt Base64 encoding uses completely different digits.
    • The salt requirements are somewhat arcane. bcrypt has 22 digits of salt, but only the first two bits of the last digit are used. So the last digit can only be ".", "O", "e" or "u". The current bcrypt implementation will fix the digit for you if you screw it up, but other implementations may be less robust.
    • And of course there's all the usual problems of cryptography: choosing a proper randomness source, making sure to not leak timing information etc.

    That's why I always recommend to not use this function unless you really, really know what you're doing. It's simply too easy to screw up.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo