Can someone point me to a good PHP/MySQL salted hashed password implementation?

后端 未结 8 700
感情败类
感情败类 2021-02-06 07:33

After reading about salts password hashing Id like to implement a simple version for an admin area to a site Im building.

If you have any good links with code that have

8条回答
  •  醉梦人生
    2021-02-06 08:09

    Well, here's what I would do:

    function makeToken($length = 16) {
        if ($length > 16) {
            $ret = '';
            while ($length > 0) {
                $ret .= makeToken(16);
                $length -= 16;
            }
            if ($length < 0) {
                $ret = substr($ret, 0, $length);
            }
            return $ret;
        }
        $stub = '';
        for ($i = 0; $i < 100; $i++) {
            $stub .= chr(mt_rand(1, 254));                
        }
        $hash = sha1($stub);
        $hashLen = strlen($hash);
        $ret = '';
        for ($i = 0; $i < $length; $i++) {
            $ret .= $hash[mt_rand(0, $hashLen - 1)];
        }
        return $ret;
    }
    
    function makeSaltedHash($string, $salt = '') {
        if (empty($salt)) { 
            $salt = makeToken();
        }
        $hash = '';
        for ($i = 0; $i < 200; $i++) {
            $hash = sha1($hash . $salt . $string);
        }
        return $hash . ':' . $salt;
    }
    
    function verifySaltedHash($string, $hash) {
        if (strpos($string, ':') === false) return false;
        list ($base, $salt) = explode(':', $hash);
        $test = makeSaltedHash($string, $salt);
        return $test === $hash;
    }
    

    The rational is this:

    First, generate a random salt (this will always return a hex string, so it can be used for tokens etc). Then loop over a hashing function (sha1 in this case) more than 1 time. This is so that it becomes more expensive to generate a rainbow table (200x as expensive in this case) while adding relatively little expense to generation.

    Usage:

    To generate a hash:

    $hash = makeSaltedHash($password);
    

    To verify the hash:

    $bool = verifySaltedHash($password, $savedHash);
    

    To generate a token (CSRF protection, session_id, etc), you can do it a few ways:

    Fixed Length:

    $token = makeToken(32);
    

    Random Length:

    $token = makeToken(mt_rand(64,128));
    

    Edit: Increased the repetitions on sha1 in the hashing function.

提交回复
热议问题