41 lines
1.4 KiB
PHP
41 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Brick\Math\BigInteger;
|
|
|
|
/** The site's legacy AzerothCore SRP format, independent of the game ticket. */
|
|
class AzerothCoreSrpService
|
|
{
|
|
private const string MODULUS_HEX = '894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7';
|
|
|
|
public function makeRegistrationData(string $username, string $password): array
|
|
{
|
|
$saltHex = strtoupper(bin2hex(random_bytes(32)));
|
|
|
|
return [$saltHex, $this->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));
|
|
}
|
|
}
|