PHP的password_hash如何生成盐?

你好,你可能知道PHP最近推出了password_hash内置的最新版本.文件说:

If omitted, a random salt will be created and the default cost will be used.

问题是它添加盐的方法是什么?

我很感兴趣,因为我想知道盐是否是随机创建的,所以当我存储我的哈希密码时,它们总是唯一的.

解决方法:

盐是随机产生的.它们应该具有统计独特性.

要了解具体方法,请查看the C source code.

在Windows上,它将尝试使用PHP_win32_get_random_bytes()来生成salt:

BYTE *iv_b = (BYTE *) buffer;
if (PHP_win32_get_random_bytes(iv_b, raw_length) == SUCCESS) {
    buffer_valid = 1;
}

在Linux上,它将尝试读取/ dev / urandom来生成salt:

int fd, n;
size_t read_bytes = 0;
fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
    while (read_bytes < raw_length) {
        n = read(fd, buffer + read_bytes, raw_length - read_bytes);
        if (n < 0) {
            break;
        }
        read_bytes += (size_t) n;
    }
    close(fd);
}
if (read_bytes >= raw_length) {
    buffer_valid = 1;
}

然后,在这两个之后,如果缓冲区无效(未满,可能是部分),则使用rand()将其填满.请注意,在实践中,这绝不应该发生,它只是一个后备:

if (!buffer_valid) {
    for (i = 0; i < raw_length; i++) {
        buffer[i] ^= (char) (255.0 * PHP_rand(TSrmlS_C) / RAND_MAX);
    }
}

现在,如果C不是你的一杯茶,那么在my compat library中用PHP实现了相同的逻辑和算法:

$buffer = '';
$raw_length = (int) ($required_salt_len * 3 / 4 + 1);
$buffer_valid = false;
if (function_exists('mcrypt_create_iv')) {
    $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM);
    if ($buffer) {
        $buffer_valid = true;
    }
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
    $buffer = openssl_random_pseudo_bytes($raw_length);
    if ($buffer) {
        $buffer_valid = true;
    }
}
if (!$buffer_valid && is_readable('/dev/urandom')) {
    $f = fopen('/dev/urandom', 'r');
    $read = strlen($buffer);
    while ($read < $raw_length) {
        $buffer .= fread($f, $raw_length - $read);
        $read = strlen($buffer);
    }
    fclose($f);
    if ($read >= $raw_length) {
        $buffer_valid = true;
    }
}
if (!$buffer_valid || strlen($buffer) < $raw_length) {
    $bl = strlen($buffer);
    for ($i = 0; $i < $raw_length; $i++) {
        if ($i < $bl) {
            $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
        } else {
            $buffer .= chr(mt_rand(0, 255));
        }
    }
}

唯一的区别是PHP版本将使用mcrypt或openssl如果安装了…

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...