makeVerifierHex($username, $password, $saltHex)]; } public function makeVerifierHex(string $username, string $password, string $saltHex): string { $salt = hex2bin($saltHex); if ($salt === false || strlen($salt) !== 32) { throw new \InvalidArgumentException('Invalid site credential salt.'); } $digest = hash('sha1', strtoupper(trim($username)).':'.strtoupper($password), true); $x = hash('sha1', $salt.$digest, true); $verifier = BigInteger::of(7)->modPow( BigInteger::fromBytes(strrev($x), false), BigInteger::fromBase(self::MODULUS_HEX, 16), ); return strtoupper(bin2hex(strrev(str_pad($verifier->toBytes(false), 32, "\0", STR_PAD_LEFT)))); } public function credentialsMatch(string $username, string $password, string $saltHex, string $verifierHex): bool { return hash_equals(strtoupper($verifierHex), $this->makeVerifierHex($username, $password, $saltHex)); } }