我正在使用Laravel Hash Facade生成哈希。然后将其传递给第三方服务,该服务在回调中使用相同的哈希。我用它来确保请求是“受信任的”。但是,Hash::make()
创建了一个60个字符长的字符串,但是第三方服务仅允许32个字符。
如果我将md5()
应用于哈希,将无法使用Hash::check()
。如果我使用substr()
,则两个-或更多-散列可以导致相同的字符串。
以一种安全的方式处理这种情况的最佳方法是什么?
答案 0 :(得分:1)
默认情况下,Laravel Hash将password_hash()
函数与BLOWFISH密码结合使用,可生成60个字符的结果。但是,60个字符的结果实际上是28个字符的参数,以及由此产生的32个字符的哈希。
前28个字符由4个字符的前缀($2y$
),2位数字的费用(04 - 31
)和22个字符的salt组成。如果您将前28个字符存储在应用程序中的某个位置(例如.env
文件),则可以使用它来检查您从第三方生成和接收的32个字符哈希。
password_hash()
函数是crypt()
函数的内置包装器,但它动态生成自己的盐。由于Laravel没有提供手动提供盐的方法,因此您将无法使用Hash::make()
方法;您将需要直接使用crypt()
方法,并传递适当的数据以使用带有静态盐的BLOWFISH密码进行触发。不过,生成的结果仍与password_verify()
函数兼容,因此您仍然可以使用Hash::check()
来验证接收到的哈希(或直接使用password_verify()
)。
希望下面是带有代码和注释的更有用的插图。
// This tells crypt() to use the BLOWFISH cypher
$prefix = '$2y$';
// This tells crypt() the number of rounds for the BLOWFISH algorithm to use.
// The higher the number, the longer it takes to generate a hash (good).
// Value must be two digits and between 04 and 31. 10 is default.
$cost = '10';
// This is the 22 character salt (including start and end dollar signs). This is
// the value normally dynamically generated by password_hash(), but you
// are storing a static value in your application.
$salt = '$thisisahardcodedsalt$';
// Concat the three parameters to generate the full 28 character BLOWFISH
// prefix. Instead of using the hardcoded variables above, you would
// probably just get the value out of the config (set by .env file).
$blowfishPrefix = $prefix.$cost.$salt;
// I don't know where your password is coming from, but this is the password
// that you were planning on using for your Hash::make() and Hash::check()
// calls.
$password = 'This is your password.';
// Hash the password to get your 60 character BLOWFISH cipher result.
$hash = crypt($password, $blowfishPrefix);
// The real hash is the last 32 characters. This is the value you pass to your
// third party service.
$hashToThirdParty = substr($hash, -32);
// Now we've generated a hash and sent it to the third party. Now we wait.
// ... at some point, the third party sends the hash back to you.
$hashFromThirdParty = $hashToThirdParty;
// Add your stored BLOWFISH prefix to the hash received from the third party,
// and pass the result into Hash::check() (along with your password).
$verified = Hash::check($password, $blowfishPrefix.$hashFromThirdParty);
// Since we're not using Hash::make() to generate the password, you may not care
// about using Hash::check() to check it. You can just use the underlying
// password_verify() function at this point, if you want.
$altVerified = password_verify($password, $blowfishPrefix.$hashFromThirdParty);
PHP函数资源:
password_hash()
crypt()
password_verify()
Laravel代码资源:
Hash::make()
for the bcrypt hasher
Hash::check()
for the bcrypt hasher