Can someone point me to a good PHP/MySQL salted ha

2019-03-16 05:57发布

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 implemented this idea well, I would appreciate it if you could share.

Thanks,

8条回答
孤傲高冷的网名
2楼-- · 2019-03-16 06:06

I don't have a link to available code, but what I've done in the past is to generate a randomized salt - $salt = rand(1,1000000000); - and save it in a session. I pass that salt to a login page and then use JavaScript to create a SHA hash of the salt + password which is submitted rather than a plaintext password. Since the salt is stored in the session I can then use that to see if the login hash matches the salt + password hash stored in the db.

查看更多
聊天终结者
3楼-- · 2019-03-16 06:07

the code is simple, and dan heberden has already provided it.

a salt is simply a piece of text that you append or prepend to a password before generating a hash. eg, if your password is 'password' and the salt is 'salt' then the hash will be hashFunction('saltpassword') instead of hashFunction('password').

salts are generally used to avoid rainbow password cracks - this is where a large list of passwords and their hashes are checked against the hashed password. eg in the above example, say there is a hash 123456 which corresponds to hashFunction('password'), if the attacker knows your hash is 123456 then they know your password is 'password'.

your salt should be a random string of letters and numbers - eg kjah!!sdf986. it's very very unlikely for someone to have a rainbow table including kjah!!sdf986password so even if someone gets your hashed password then it's kinda useless.

however, you obviously need to use the same salt every time, or at least store the salt as well as the password. because if you pick a random salt every time chances are your hashed salt+password will not be the same :D

查看更多
再贱就再见
4楼-- · 2019-03-16 06:10

There are so many ways you can create a salt string, but i think you don't need to think a lot about your salt strength.

I hash passwords like this

$hash = sha1(strlen($password) . md5($password) . $salt);

I think its the best performance between speed, and "security".

function salt($lenght = 9) {
    $numbers = '0123456789';
    $chars = 'qwertzuiopasdfghjklyxcvbnm';

    $password = '';
    $alt = time() % 2;
    for ($i = 0; $i < $length; $i++) {
        if ($alt == 1) 
        {
            $password .= $chars[(rand() % strlen($chars))];
            $alt = 0;
        } else 
        {
            $password .= $numbers[(rand() % strlen($numbers))];
            $alt = 1;
        }
    }
    return $password;
}
查看更多
\"骚年 ilove
5楼-- · 2019-03-16 06:11

If you need really secure hashes, please use the Portable PHP hashing framework.

I'd also recommend this Month of PHP security article that deals extensively with password hashing and the security of hashes.

查看更多
祖国的老花朵
6楼-- · 2019-03-16 06:13

Could you use the built in crypt(...) function?

... Usage ...

crypt('rasmuslerdorf', '$1$rasmusle$')

... Result ...

MD5: $1$rasmusle$rISCgZzpwk3UhDidwXvin0

... There are more examples and other hash methods available in the documentation.

查看更多
小情绪 Triste *
7楼-- · 2019-03-16 06:17

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.

查看更多
登录 后发表回答