在PHP中正确使用带有SHA512的crypt()

Sha*_*Zzz 5 php crypt password-encryption

在线的所有示例都显示了如下所示的crypt的使用:

$pass = crypt('something','$6$rounds=5000$anexamplestringforsalt$');
Run Code Online (Sandbox Code Playgroud)

但是每个人都说你不应该定义轮次或盐.

那我该怎么用呢?

另外我遇到了一个问题:当我运行上面的代码时,它只运行50轮而不是5000轮,就像系统停止它一样.

任何帮助将不胜感激.

// - 解决方案 - //

我发现其中一些有用:

用于生成盐:

 $salt = substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345??6789"), 0, 8); 
Run Code Online (Sandbox Code Playgroud)

要么

如果你有一个linux服务器,这是一种更随机的生成盐的方法

$fp = fopen('/dev/urandom', 'r');
$randomString = fread($fp, 32);
fclose($fp);
Run Code Online (Sandbox Code Playgroud)

Base 64编码以确保某些字符不会导致crypt出现问题

$salt = base64_encode($randomString);
Run Code Online (Sandbox Code Playgroud)

对于哈希:

$hashed = crypt($passwordInput, '$6$'.$salt);
Run Code Online (Sandbox Code Playgroud)

确认:

if (crypt($passwordInput, $hashed) == $hashed) { 
  // Valid action
} else { 
  // Invalid action
}
Run Code Online (Sandbox Code Playgroud)

**特别感谢@ lathspell帮助我们解决上述问题**

lat*_*ell 5

将算法运行一定数量的轮次的主要原因只是为了减慢它的速度,使蛮力攻击变得无趣。即使对于现代硬件,5000 次迭代也足够了。您也可以使用 100000,但是您的服务器管理员可能会想和您谈谈 :-) rounds=5000 是 SHA-512 的默认值。最小值为 1000,最大值非常高。

  • 加密: $salt = substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 8); $hashed = crypt($passwordInput, '$6$'.$salt); 验证: if (crypt($passwordInput, $hashed) == $hashed) { echo "valid"; } else { 回声“无效”;} (2认同)
  • 为了不受到定时攻击,应该使用“hash_equals”函数而不是“==”。 (2认同)

小智 5

使用OpenSSL进行salt生成,更加随机。也许需要 20000 轮才能让你的代码面向未来。

function cryptPassword($password, $salt = "", $rounds = 20000)
{
    if ($salt == "")
    {
        // Generate random salt
        $salt = substr(bin2hex(openssl_random_pseudo_bytes(16)),0,16);
    }
    // $6$ specifies SHA512
    $hash = crypt($password, sprintf('$6$rounds=%d$%s$', $rounds, $salt));

    return $hash;
}
Run Code Online (Sandbox Code Playgroud)