PHP Classes

File: docs/guides/hotp.rst

Recommend this page to a friend!
  Packages of A. B. M. Mahmudul Hasan   OTP   docs/guides/hotp.rst   Download  
File: docs/guides/hotp.rst
Role: Example script
Content type: text/plain
Description: Example script
Class: OTP
Generate token to be verified during a time window
Author: By
Last change:
Date: 20 days ago
Size: 2,883 bytes
 

Contents

Class file image Download
HOTP Guide
==========

RFC context
-----------

HOTP is defined in RFC4226. Unlike TOTP, it is driven by a moving counter rather than wall-clock time.

That means:

- both sides must agree on a counter
- every successful authentication normally advances the server-side counter state
- resynchronization is a practical concern in real deployments

Basic usage
-----------

Generating a secret
-------------------

You can generate a new Base32 secret directly from the HOTP class:

.. code-block:: php

   <?php
  
use Infocyph\OTP\HOTP;

  
$secret = HOTP::generateSecret();

Creating an HOTP instance
-------------------------

..
code-block:: php

  
<?php
  
use Infocyph\OTP\HOTP;

  
$hotp = (new HOTP($secret))
       ->
setCounter(3)
       ->
setAlgorithm('sha1');

  
$otp = $hotp->getOTP(10);
  
$hotp->verify($otp, 10);

Generating OTPs
---------------

..
code-block:: php

  
<?php
   $counter
= 346;
  
$otp = $hotp->getOTP($counter);

Basic verification
------------------

..
code-block:: php

  
<?php
   $isValid
= $hotp->verify($otp, 346);

Look-ahead verification
-----------------------

HOTP often needs controlled counter resynchronization.

..
code-block:: php

  
<?php
   $hotp
->verify($otp, counter: 10, lookAhead: 5);

This means the verifier will try the provided counter and then probe forward up to the configured look-ahead window.

Rich verification result
------------------------

..
code-block:: php

  
<?php
  
use Infocyph\OTP\Stores\InMemoryReplayStore;

  
$result = $hotp->verifyWithResult(
      
$otp,
      
counter: 10,
      
lookAhead: 5,
      
replayStore: new InMemoryReplayStore(),
      
binding: 'device-1',
   );

  
$result->matched;
  
$result->matchedCounter;
  
$result->driftOffset;
  
$result->replayDetected;

Typical server pattern
----------------------

In a stateful HOTP deployment, a common flow is:

1. load the user or device counter
2. verify using a small look
-ahead window
3.
if matched, persist the returned ``matchedCounter``
4. reject any already-used counter value

Example
:

..
code-block:: php

  
<?php
   $storedCounter
= 100;

  
$result = $hotp->verifyWithResult(
      
$submittedOtp,
      
counter: $storedCounter,
      
lookAhead: 5,
      
replayStore: $store,
      
binding: 'device-1',
   );

   if (
$result->matched) {
      
$nextCounter = $result->matchedCounter;
      
// persist the new server-side counter state
  
}

Provisioning
------------

HOTP is also commonly shared via ``otpauth://`` URIs, especially when interoperating with authenticator clients that support event-based counters.

.. code-block:: php

  
<?php
   $uri
= $hotp->getProvisioningUri('alice@example.com', 'Example App');

QR example:

..
code-block:: php

  
<?php
   $svg
= $hotp->getProvisioningUriQR('alice@example.com', 'Example App');

See :doc:`provisioning` for additional provisioning and QR examples.