限制Laravel中哈希的长度

时间:2018-12-16 18:47:31

标签: laravel

我正在使用Laravel Hash Facade生成哈希。然后将其传递给第三方服务,该服务在回调中使用相同的哈希。我用它来确保请求是“受信任的”。但是,Hash::make()创建了一个60个字符长的字符串,但是第三方服务仅允许32个字符。

如果我将md5()应用于哈希,将无法使用Hash::check()。如果我使用substr(),则两个-或更多-散列可以导致相同的字符串。

以一种安全的方式处理这种情况的最佳方法是什么?

1 个答案:

答案 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