• Stars
    star
    8
  • Rank 2,099,232 (Top 42 %)
  • Language
    PHP
  • License
    MIT License
  • Created about 4 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple but Secure Generic OTP, TOTP (RFC6238) & HOTP (RFC4226) solution!

OTP

Codacy Badge Libraries.io dependency status for GitHub repo Packagist Downloads (custom server) License: MIT Packagist Version Packagist PHP Version GitHub code size in bytes

Simple but Secure Generic OTP, TOTP (RFC6238), HOTP (RFC4226) solution!

Prerequisites

Language: PHP 8.2/+

Library Version PHP Version
3.x.x 8.2.x or Higher
2.x.x 8.x.x
1.x.x 7.x.x

Installation

composer require abmmhasan/otp

Why this library?

TOTP & HOTP

  • Uses offline QR code generator (no more exposing your secret online)
  • Time-safe Base32 encoding (30 seconds validity means 30 seconds)

Generic OTP

  • No need to dedicate extra storage/db for User information (just build a unique signature)

Usage

HOTP (RFC4226)

/**
* Generate Secret
* It will generate secure random secret string
*/
$secret = \AbmmHasan\OTP\HOTP::generateSecret();

/**
* Get QR Code Image for secret $secret
*/
// supports digit count in 2nd parameter, recommended to be either 6 or 8 (default 6)
(new \AbmmHasan\OTP\HOTP($secret))
// only required if the counter is being imported from another system or if it is old, & for QR only
->setCounter(3)
// default is sha1; Caution: many app (in fact, most of them) have algorithm limitation
->setAlgorithm('sha256') 
// or `getProvisioningUri` just to get the URI
->getProvisioningUriQR('TestName', '[email protected]'); 

/**
* Get current OTP for a given counter
*/
$counter = 346;
$otp = (new \AbmmHasan\OTP\HOTP($secret))->getOTP($counter);

/**
* Verify
*/
(new \AbmmHasan\OTP\HOTP($secret))->verify($otp,$counter);

TOTP (RFC6238)

/**
* Generate Secret
* It will generate secure random secret string
*/
$secret = \AbmmHasan\OTP\TOTP::generateSecret();

/**
* Get QR Code Image for secret $secret
*/
// supports digit count in 2nd parameter, recommended to be either 6 or 8 (default 6)
(new \AbmmHasan\OTP\TOTP($secret)) 
// default is sha1; Caution: many app (in fact, most of them) have algorithm limitation
->setAlgorithm('sha256') 
// or `getProvisioningUri` just to get the URI
->getProvisioningUriQR('TestName', '[email protected]');

/**
* Get current OTP
*/
$otp = (new \AbmmHasan\OTP\TOTP($secret))->getOTP();
// or get OTP for another specified epoch time
$otp = (new \AbmmHasan\OTP\TOTP($secret))->getOTP(1604820275);

/**
* Verify
* 
* on 3rd parameter it supports, enabling leeway.
* if enabled, it will also check with last segment's generated otp 
*/
(new \AbmmHasan\OTP\TOTP($secret))->verify($otp);
// or verify for a specified time
(new \AbmmHasan\OTP\TOTP($secret))->verify($otp, 1604820275);

Generic OTP

/**
* Initiate 
* Param 1 is OTP length (default 6)
* Param 2 is validity in seconds (default 30)
* Param 3 is retry count on failure (default 3)
*/
$otpInstance = new \AbmmHasan\OTP\OTP(4, 60, 2);

/**
* Generate & get the OTP
*/
$otp = $otpInstance->generate('an unique signature for a cause');

/**
* Verify the OTP
* 
* on 3rd parameter setting false will keep the record till the otp is verified or expired
* by default it will keep the record till the key name match or the otp is verified or expired
*/
$otpInstance->verify('an unique signature for a cause', $otp);

/**
* Delete the record
*/
$otpInstance->delete('an unique signature for a cause');

/**
* Flush all the existing OTPs (if any)
*/
$otpInstance->flush()

Note: Generic OTP uses temporary location for storage, make sure you have proper access permission

Support

Having trouble? Create an issue!