34 'algo' => $this->config[
'algo'],
35 'rounds' => $this->config[
'cost'],
36 'length' => $this->config[
'length']
45 return $this->config[
'use-hash-extension'] ?? function_exists(
'hash_pbkdf2' );
48 public function crypt( $password ) {
50 $this->
args[] = base64_encode( random_bytes( 16 ) );
55 $this->params[
'algo'],
57 base64_decode( $this->
args[0] ),
58 (
int)$this->params[
'rounds'],
59 (
int)$this->params[
'length'],
62 if ( !is_string(
$hash ) ) {
66 $hashLenHash = hash( $this->params[
'algo'],
'',
true );
67 if ( !is_string( $hashLenHash ) ) {
70 $hashLen = strlen( $hashLenHash );
71 $blockCount = ceil( $this->params[
'length'] / $hashLen );
74 $salt = base64_decode( $this->
args[0] );
75 for ( $i = 1; $i <= $blockCount; ++$i ) {
76 $roundTotal = $lastRound = hash_hmac(
77 $this->params[
'algo'],
78 $salt . pack(
'N', $i ),
83 for ( $j = 1; $j < $this->params[
'rounds']; ++$j ) {
84 $lastRound = hash_hmac( $this->params[
'algo'], $lastRound, $password,
true );
85 $roundTotal ^= $lastRound;
91 $hash = substr(
$hash, 0, $this->params[
'length'] );
94 $this->hash = base64_encode(
$hash );