Skip to content

OTPHP

OTPHP computes and checks one-time passwords: the six digits an authenticator application shows your users for a second factor.

It implements both algorithms the specifications define. TOTP is time-based (RFC 6238) and is what almost every service uses. HOTP is counter-based (RFC 4226), the algorithm TOTP is built on. The codes are read by Google Authenticator, FreeOTP, Aegis, 1Password and the others.

use OTPHP\TOTP;

// Enrolment: one secret per account, stored with the account.
$totp = TOTP::generate($clock)
    ->withLabel('alice@example.com')
    ->withIssuer('My Service');

$user->setOtpSecret($totp->getSecret());
$uri = $totp->getProvisioningUri(); // the content of the QR code the user scans
use OTPHP\TOTP;

// Sign-in: the code the user typed, against the secret you stored.
$totp = TOTP::createFromSecret($user->getOtpSecret(), $clock);

if (! $totp->verify($code)) {
    throw new BadCredentialsException('Wrong code.');
}

One package

composer require spomky-labs/otphp

It needs PHP 8.1 or later and nothing else of consequence: a Base32 codec, the psr/clock interface, and the deprecation contracts. No framework, no container, no database.

What it does not do

It does the arithmetic and nothing around it. Storing secrets, rendering QR codes, rate-limiting attempts and remembering which codes were already used are your application's work, and Security recommendations says what that work is. A library that only hands you the right digits cannot protect an account on its own.

Where to start