PHP Conference Japan 2024

sodium_crypto_pwhash_str

(PHP 7 >= 7.2.0, PHP 8)

sodium_crypto_pwhash_str获取 ASCII 编码的哈希值

描述

sodium_crypto_pwhash_str(#[\SensitiveParameter] string $password, int $opslimit, int $memlimit): string

使用 CPU 和内存密集型哈希算法以及随机生成的盐值、内存和 CPU 限制来生成适合密码存储的 ASCII 编码哈希值。

参数

password

string; 要生成哈希值的密码。

opslimit

表示要执行的最大计算量。增加此数值将使函数需要更多的 CPU 周期来计算密钥。根据预期用途,可以使用常量将操作限制设置为适当的值,强度顺序为:SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVESODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATESODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE

memlimit

函数将使用的最大 RAM 量(以字节为单位)。有一些常量可以帮助您选择适当的值,大小顺序为:SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVESODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATESODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE。通常情况下,这些应该与匹配的 opslimit 值配对。

返回值

返回哈希后的密码。

为了从相同的密码生成相同的密码哈希,必须使用相同的 opslimitmemlimit 值。这些值嵌入到生成的哈希值中,因此验证哈希所需的一切都包含在内。这允许 sodium_crypto_pwhash_str_verify() 函数在无需为其他参数单独存储的情况下验证哈希。

示例

示例 #1 sodium_crypto_pwhash_str() 示例

<?php
$password
= 'password';
echo
sodium_crypto_pwhash_str(
$password,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

上面的示例将输出类似于以下内容

$argon2id$v=19$m=65536,t=2,p=1$oWIfdaXwWwhVmovOBc2NAQ$EbsZ+JnZyyavkafS0hoc4HdaOB0ILWZESAZ7kVGa+Iw

注释

注释:

哈希值使用 Argon2ID 算法计算,可以抵抗 GPU 和侧信道攻击。与 password_hash() 函数相比,这里没有盐参数(盐值自动生成),并且 opslimitmemlimit 参数不是可选的。

参见

添加注释

用户贡献的注释 1 条注释

4
marcus at synchromedia dot co dot uk
3 年前
如果您想确保使用 sodium_crypto_pwhash_str 生成的哈希值与 password_hash 生成的哈希值兼容,则需要注意内存设置。根据文档,password_hash 的 memory_cost 参数以“KiB”(千字节)为单位,而 sodium_crypto_pwhash_str 使用字节。我做了一些实验来查看两者之间的区别,结果如下:

echo password_hash('password',
PASSWORD_ARGON2ID,
[
'memory_cost' => 15000,
'time_cost' => 26,
'threads' => 1,
];

echo sodium_crypto_pwhash_str(
'password', 26,
15000000);

结果是:
$argon2id$v=19$m=15000,t=26,p=1$VG5MSkhUdEdFaGwyVG5sWA$laRHogIVAnC4ggLI8RdCDWlITTdicrdq0tK6SHGf4CI
$argon2id$v=19$m=14648,t=26,p=1$ClQ37/z9u7K6V1C2bkD4QA$51m8KhQQ9gujFSF+JyQR9d5QesayJiKsFmDU4HnGBHg

请注意,“m=” 的数值不同,也与我们要求的不同。这是由于“KiB”单位造成的。如果我们将 password_hash 使用的 15000 乘以 1024 而不是 1000,我们将得到 15,360,000,使用这个数字将得到预期的哈希参数。

echo sodium_crypto_pwhash_str(
'password', 26,
15360000);

$argon2id$v=19$m=15000,t=26,p=1$Qz3pWktOvT6X/LvdAk0bgQ$KosSFPfHUtWg+ppyRs3Op5/zIV6F6iy2Q7Gom8wP29c

这应该与 password_hash 兼容。

顺便说一句,我用于 Argon2id 哈希参数的数字取自 OWASP 密码指南,该指南推荐的值与 PHP 的默认值不同:https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id
To Top