public hkdf ( string $algo, string $inputKey, string $salt = null, string $info = null, integer $length ) : string | ||
$algo | string | a hash algorithm supported by `hash_hmac()`, e.g. 'SHA-256' |
$inputKey | string | the source key |
$salt | string | the random salt |
$info | string | optional info to bind the derived key material to application- and context-specific information, e.g. a user ID or API version, see [RFC 5869](https://tools.ietf.org/html/rfc5869) |
$length | integer | length of the output key in bytes. If 0, the output key is the length of the hash algorithm output. |
return | string | the derived key |
public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0)
{
$test = @hash_hmac($algo, '', '', true);
if (!$test) {
throw new InvalidParamException('Failed to generate HMAC with hash algorithm: ' . $algo);
}
$hashLength = StringHelper::byteLength($test);
if (is_string($length) && preg_match('{^\\d{1,16}$}', $length)) {
$length = (int) $length;
}
if (!is_int($length) || $length < 0 || $length > 255 * $hashLength) {
throw new InvalidParamException('Invalid length');
}
$blocks = $length !== 0 ? ceil($length / $hashLength) : 1;
if ($salt === null) {
$salt = str_repeat("", $hashLength);
}
$prKey = hash_hmac($algo, $inputKey, $salt, true);
$hmac = '';
$outputKey = '';
for ($i = 1; $i <= $blocks; $i++) {
$hmac = hash_hmac($algo, $hmac . $info . chr($i), $prKey, true);
$outputKey .= $hmac;
}
if ($length !== 0) {
$outputKey = StringHelper::byteSubstr($outputKey, 0, $length);
}
return $outputKey;
}
/** * @inheritdoc */ public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0) { return parent::hkdf($algo, $inputKey, $salt, $info, $length); }