<?php
namespace PragmaRX\Google2FA;
use PragmaRX\Google2FA\Exceptions\InvalidAlgorithmException;
use PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException;
use PragmaRX\Google2FA\Support\Base32;
use PragmaRX\Google2FA\Support\Constants;
use PragmaRX\Google2FA\Support\QRCode;
class Google2FA
{
use QRCode;
use Base32;
/**
* Algorithm.
*
* @var string
*/
protected $algorithm = Constants::SHA1;
/**
* Length of the Token generated.
*
* @var int
*/
protected $oneTimePasswordLength = 6;
/**
* Interval between key regeneration.
*
* @var int
*/
protected $keyRegeneration = 30;
/**
* Secret.
*
* @var string
*/
protected $secret;
/**
* Window.
*
* @var int
*/
protected $window = 1; // Keys will be valid for 60 seconds
/**
* Find a valid One Time Password.
*
* @param string $secret
* @param string $key
* @param int|null $window
* @param int $startingTimestamp
* @param int $timestamp
* @param int|null $oldTimestamp
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return bool|int
*/
public function findValidOTP(
$secret,
$key,
$window,
$startingTimestamp,
$timestamp,
$oldTimestamp = null
) {
for (;
$startingTimestamp <= $timestamp + $this->getWindow($window);
$startingTimestamp++
) {
if (
hash_equals($this->oathTotp($secret, $startingTimestamp), $key)
) {
return is_null($oldTimestamp)
? true
: $startingTimestamp;
}
}
return false;
}
/**
* Generate the HMAC OTP.
*
* @param string $secret
* @param int $counter
*
* @return string
*/
protected function generateHotp($secret, $counter)
{
return hash_hmac(
$this->getAlgorithm(),
pack('N*', 0, $counter), // Counter must be 64-bit int
$secret,
true
);
}
/**
* Generate a digit secret key in base32 format.
*
* @param int $length
* @param string $prefix
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
*
* @return string
*/
public function generateSecretKey($length = 16, $prefix = '')
{
return $this->generateBase32RandomKey($length, $prefix);
}
/**
* Get the current one time password for a key.
*
* @param string $secret
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return string
*/
public function getCurrentOtp($secret)
{
return $this->oathTotp($secret, $this->getTimestamp());
}
/**
* Get the HMAC algorithm.
*
* @return string
*/
public function getAlgorithm()
{
return $this->algorithm;
}
/**
* Get key regeneration.
*
* @return int
*/
public function getKeyRegeneration()
{
return $this->keyRegeneration;
}
/**
* Get OTP length.
*
* @return int
*/
public function getOneTimePasswordLength()
{
return $this->oneTimePasswordLength;
}
/**
* Get secret.
*
* @param string|null $secret
*
* @return string
*/
public function getSecret($secret = null)
{
return is_null($secret) ? $this->secret : $secret;
}
/**
* Returns the current Unix Timestamp divided by the $keyRegeneration
* period.
*
* @return int
**/
public function getTimestamp()
{
return (int) floor(microtime(true) / $this->keyRegeneration);
}
/**
* Get a list of valid HMAC algorithms.
*
* @return array
*/
protected function getValidAlgorithms()
{
return [
Constants::SHA1,
Constants::SHA256,
Constants::SHA512,
];
}
/**
* Get the OTP window.
*
* @param null|int $window
*
* @return int
*/
public function getWindow($window = null)
{
return is_null($window) ? $this->window : $window;
}
/**
* Make a window based starting timestamp.
*
* @param int|null $window
* @param int $timestamp
* @param int|null $oldTimestamp
*
* @return mixed
*/
private function makeStartingTimestamp($window, $timestamp, $oldTimestamp = null)
{
return is_null($oldTimestamp)
? $timestamp - $this->getWindow($window)
: max($timestamp - $this->getWindow($window), $oldTimestamp + 1);
}
/**
* Get/use a starting timestamp for key verification.
*
* @param string|int|null $timestamp
*
* @return int
*/
protected function makeTimestamp($timestamp = null)
{
if (is_null($timestamp)) {
return $this->getTimestamp();
}
return (int) $timestamp;
}
/**
* Takes the secret key and the timestamp and returns the one time
* password.
*
* @param string $secret Secret key in binary form.
* @param int $counter Timestamp as returned by getTimestamp.
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return string
*/
public function oathTotp($secret, $counter)
{
if (strlen($secret) < 8) {
throw new SecretKeyTooShortException();
}
$secret = $this->base32Decode($this->getSecret($secret));
return str_pad(
$this->oathTruncate($this->generateHotp($secret, $counter)),
$this->getOneTimePasswordLength(),
'0',
STR_PAD_LEFT
);
}
/**
* Extracts the OTP from the SHA1 hash.
*
* @param string $hash
*
* @return string
**/
public function oathTruncate($hash)
{
$offset = ord($hash[strlen($hash) - 1]) & 0xF;
$temp = unpack('N', substr($hash, $offset, 4));
$temp = $temp[1] & 0x7FFFFFFF;
return substr(
(string) $temp,
-$this->getOneTimePasswordLength()
);
}
/**
* Remove invalid chars from a base 32 string.
*
* @param string $string
*
* @return string|null
*/
public function removeInvalidChars($string)
{
return preg_replace(
'/[^'.Constants::VALID_FOR_B32.']/',
'',
$string
);
}
/**
* Setter for the enforce Google Authenticator compatibility property.
*
* @param mixed $enforceGoogleAuthenticatorCompatibility
*
* @return $this
*/
public function setEnforceGoogleAuthenticatorCompatibility(
$enforceGoogleAuthenticatorCompatibility
) {
$this->enforceGoogleAuthenticatorCompatibility = $enforceGoogleAuthenticatorCompatibility;
return $this;
}
/**
* Set the HMAC hashing algorithm.
*
* @param mixed $algorithm
*
* @throws \PragmaRX\Google2FA\Exceptions\InvalidAlgorithmException
*
* @return \PragmaRX\Google2FA\Google2FA
*/
public function setAlgorithm($algorithm)
{
// Default to SHA1 HMAC algorithm
if (!in_array($algorithm, $this->getValidAlgorithms())) {
throw new InvalidAlgorithmException();
}
$this->algorithm = $algorithm;
return $this;
}
/**
* Set key regeneration.
*
* @param mixed $keyRegeneration
*/
public function setKeyRegeneration($keyRegeneration)
{
$this->keyRegeneration = $keyRegeneration;
}
/**
* Set OTP length.
*
* @param mixed $oneTimePasswordLength
*/
public function setOneTimePasswordLength($oneTimePasswordLength)
{
$this->oneTimePasswordLength = $oneTimePasswordLength;
}
/**
* Set secret.
*
* @param mixed $secret
*/
public function setSecret($secret)
{
$this->secret = $secret;
}
/**
* Set the OTP window.
*
* @param mixed $window
*/
public function setWindow($window)
{
$this->window = $window;
}
/**
* Verifies a user inputted key against the current timestamp. Checks $window
* keys either side of the timestamp.
*
* @param string $key User specified key
* @param string $secret
* @param null|int $window
* @param null|int $timestamp
* @param null|int $oldTimestamp
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return bool|int
*/
public function verify(
$key,
$secret,
$window = null,
$timestamp = null,
$oldTimestamp = null
) {
return $this->verifyKey(
$secret,
$key,
$window,
$timestamp,
$oldTimestamp
);
}
/**
* Verifies a user inputted key against the current timestamp. Checks $window
* keys either side of the timestamp.
*
* @param string $secret
* @param string $key User specified key
* @param int|null $window
* @param null|int $timestamp
* @param null|int $oldTimestamp
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return bool|int
*/
public function verifyKey(
$secret,
$key,
$window = null,
$timestamp = null,
$oldTimestamp = null
) {
$timestamp = $this->makeTimestamp($timestamp);
return $this->findValidOTP(
$secret,
$key,
$window,
$this->makeStartingTimestamp($window, $timestamp, $oldTimestamp),
$timestamp,
$oldTimestamp
);
}
/**
* Verifies a user inputted key against the current timestamp. Checks $window
* keys either side of the timestamp, but ensures that the given key is newer than
* the given oldTimestamp. Useful if you need to ensure that a single key cannot
* be used twice.
*
* @param string $secret
* @param string $key User specified key
* @param int|null $oldTimestamp The timestamp from the last verified key
* @param int|null $window
* @param int|null $timestamp
*
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
*
* @return bool|int
*/
public function verifyKeyNewer(
$secret,
$key,
$oldTimestamp,
$window = null,
$timestamp = null
) {
return $this->verifyKey(
$secret,
$key,
$window,
$timestamp,
$oldTimestamp
);
}
}
The Kueue Pay Payment Gateway is an innovative technology that facilitates seamless and secure transactions between merchants and their customers. It enables businesses to accept debit and credit card payments both online and in physical stores.
The Kueue Pay Payment Gateway acts as a bridge between a merchant’s website or point-of-sale system and the payment processing network. It securely transmits payment information, authorizes transactions, and provides real-time status updates.
The Kueue Pay Developer API empowers developers and entrepreneurs to integrate the Kueue Pay Payment Gateway directly into their websites or applications. This streamlines the payment process for customers and provides businesses with a customizable and efficient payment solution.
To access the Kueue Pay Developer API, you need to sign up for a developer account on our platform. Once registered, you’ll receive an API key that you can use to authenticate your API requests.
The Kueue Pay Developer API allows you to initiate payments, check the status of payments, and process refunds. You can create a seamless payment experience for your customers while maintaining control over transaction management.
Yes, the Kueue Pay Developer API is designed to accommodate businesses of varying sizes and industries. Whether you’re a small online store or a large enterprise, our API can be tailored to fit your specific payment needs.
The Kueue Pay Developer API is designed with simplicity and ease of use in mind. Our comprehensive documentation, code samples, and developer support resources ensure a smooth integration process for any web platform.
We offer competitive pricing plans for using the Kueue Pay Payment Gateway and Developer API. Details about fees and pricing tiers can be found on our developer portal.
Absolutely, the Kueue Pay Developer API offers customization options that allow you to tailor the payment experience to match your brand and user interface. You can create a seamless and cohesive payment journey for your customers.
We provide dedicated developer support to assist you with any issues or questions you may have during the API integration process. Reach out to our support team at developersupport@NFCPay.com for prompt assistance.
Remember, our goal is to empower your business with a robust and efficient payment solution. If you have any additional questions or concerns, feel free to explore our developer portal or contact our support team.