Add OTP support with implementation for creation, deletion, and verification.
This commit is contained in:
parent
d9c8208310
commit
866bb90f2a
8 changed files with 572 additions and 28 deletions
|
@ -7,15 +7,17 @@
|
|||
|
||||
class OtpCryptography
|
||||
{
|
||||
private const string URI_FORMAT = 'otpauth://totp/%s?secret=%s%s&algorithm=%s&digits=%d&period=%d';
|
||||
|
||||
/**
|
||||
* Generates a random secret key of the specified length.
|
||||
*
|
||||
* @param int $length The length of the secret key in bytes. Default is 32.
|
||||
* @return string Returns the generated secret key as a hexadecimal string.
|
||||
* @throws CryptographyException
|
||||
* @throws RandomException
|
||||
* @throws CryptographyException If the length is less than or equal to 0.
|
||||
* @throws RandomException If an error occurs while generating random bytes.
|
||||
*/
|
||||
public static function generateSecretKey(int $length = 32): string
|
||||
public static function generateSecretKey(int $length=32): string
|
||||
{
|
||||
if($length <= 0)
|
||||
{
|
||||
|
@ -32,11 +34,11 @@
|
|||
* @param int $timeStep The time step in seconds used for OTP generation. Default is 30 seconds.
|
||||
* @param int $digits The number of digits in the OTP. Default is 6.
|
||||
* @param int|null $counter Optional counter value. If not provided, it is calculated based on the current time and time step.
|
||||
* @param string $hashAlgorithm The hash algorithm used for OTP generation. Default is 'sha1'.
|
||||
* @param string $hashAlgorithm The hash algorithm used for OTP generation. Default is 'sha512'.
|
||||
* @return string Returns the generated OTP as a string with the specified number of digits.
|
||||
* @throws CryptographyException If the generated hash length is less than 20 bytes.
|
||||
*/
|
||||
public static function generateOTP(string $secretKey, int $timeStep=30, int $digits=6, int $counter=null, string $hashAlgorithm='sha1'): string
|
||||
public static function generateOTP(string $secretKey, int $timeStep=30, int $digits=6, int $counter=null, string $hashAlgorithm='sha512'): string
|
||||
{
|
||||
if ($counter === null)
|
||||
{
|
||||
|
@ -73,6 +75,7 @@
|
|||
* @param int $digits The number of digits in the OTP. Default is 6.
|
||||
* @param string $hashAlgorithm The hash algorithm used for OTP generation. Default is 'sha512'.
|
||||
* @return bool Returns true if the OTP is valid within the provided parameters, otherwise false.
|
||||
* @throws CryptographyException If the generated hash length is less than 20 bytes.
|
||||
*/
|
||||
public static function verifyOTP(string $secretKey, string $otp, int $timeStep=30, int $window=1, int $digits=6, string $hashAlgorithm='sha512'): bool
|
||||
{
|
||||
|
@ -93,28 +96,20 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a QR code payload for a TOTP-based authentication system.
|
||||
* Generates a key URI for use in configuring an authenticator application.
|
||||
*
|
||||
* The method constructs a URI in the format compatible with TOTP applications.
|
||||
*
|
||||
* @param string $account The account name or identifier associated with the QR code.
|
||||
* @param string $secretKey The secret key to be included in the payload.
|
||||
* @param string $issuer The issuer name to identify the organization or service.
|
||||
*
|
||||
* @return string A formatted string representing the QR code payload.
|
||||
*
|
||||
* @throws CryptographyException If the domain configuration is missing.
|
||||
* @param string $label A unique label to identify the account (e.g., user or service name).
|
||||
* @param string $secretKey The secret key used for generating the OTP.
|
||||
* @param string|null $issuer The name of the organization or service issuing the key. Default is null.
|
||||
* @param int $timeStep The time step in seconds used for OTP generation. Default is 30 seconds.
|
||||
* @param int $digits The number of digits in the generated OTP. Default is 6.
|
||||
* @param string $hashAlgorithm The hash algorithm used for OTP generation. Default is 'sha512'.
|
||||
* @return string Returns the URI string formatted
|
||||
*/
|
||||
public static function generateQrPayload(string $account, string $secretKey, string $issuer): string
|
||||
public static function generateKeyUri(string $label, string $secretKey, ?string $issuer = null, int $timeStep=30, int $digits=6, string $hashAlgorithm='sha512'): string
|
||||
{
|
||||
$domain = Configuration::getInstanceConfiguration()->getDomain();
|
||||
|
||||
if (!$domain)
|
||||
{
|
||||
throw new CryptographyException("Domain configuration is missing.");
|
||||
}
|
||||
|
||||
return sprintf("otpauth://totp/%s:%s?secret=%s&issuer=%s", rawurlencode($domain), rawurlencode($account), rawurlencode($secretKey), rawurlencode($issuer));
|
||||
$issuerPart = $issuer ? "&issuer=" . rawurlencode($issuer) : '';
|
||||
return sprintf(self::URI_FORMAT, rawurlencode($label), $secretKey, $issuerPart, strtoupper($hashAlgorithm), $digits, $timeStep);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,15 +118,14 @@
|
|||
* @param string $algorithm The hashing algorithm to be used (e.g., 'sha1', 'sha256', 'sha384', 'sha512').
|
||||
* @param string $data The data to be hashed.
|
||||
* @param string $key The secret key used for the HMAC generation.
|
||||
*
|
||||
* @return string The generated HMAC as a raw binary string.
|
||||
*
|
||||
* @*/
|
||||
* @throws CryptographyException If the algorithm is not supported.
|
||||
*/
|
||||
private static function hashHmac(string $algorithm, string $data, string $key): string
|
||||
{
|
||||
return match($algorithm)
|
||||
{
|
||||
'sha1', 'sha256', 'sha384', 'sha512' => hash_hmac($algorithm, $data, $key, true),
|
||||
'sha1', 'sha256', 'sha512' => hash_hmac($algorithm, $data, $key, true),
|
||||
default => throw new CryptographyException('Algorithm not supported')
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue