PHPackages                             remotemerge/totp-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. remotemerge/totp-php

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

remotemerge/totp-php
====================

Lightweight, fast, and secure TOTP (2FA) authentication library for PHP — battle tested, dependency free, and ready for enterprise integration.

v1.3.0(1mo ago)2118.5k↓20.2%4MITPHPPHP ^8.1CI passing

Since Dec 28Pushed 1mo ago2 watchersCompare

[ Source](https://github.com/remotemerge/totp-php)[ Packagist](https://packagist.org/packages/remotemerge/totp-php)[ Docs](https://github.com/remotemerge/totp-php)[ RSS](/packages/remotemerge-totp-php/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (8)Dependencies (6)Versions (17)Used By (0)

**TOTP PHP: The Ultimate 2FA Library for PHP**
==============================================

[](#totp-php-the-ultimate-2fa-library-for-php)

[![PHP Version](https://camo.githubusercontent.com/7ee933b2bbaad985bb7a555475e94613b196ce16a2d6152e798e8b1ef460c829/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f72656d6f74656d657267652f746f74702d7068703f6c6f676f3d706870267374796c653d666c6174)](https://github.com/remotemerge/totp-php)[![Tests](https://camo.githubusercontent.com/95aaa9a9df1adb294056e45ccdab8b2b6957b2134c1381d63eccac3a87bcda3c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f72656d6f74656d657267652f746f74702d7068702f746573742e796d6c3f7374796c653d666c6174266c6f676f3d636f756e746572737472696b65266c6162656c3d74657374)](https://github.com/remotemerge/totp-php)[![Build](https://camo.githubusercontent.com/c9951b5e00ab75156dd7cdd55b3626ea33d8918d5fa1c6522bb2c6e56fa1e37b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f72656d6f74656d657267652f746f74702d7068702f696e7374616c6c2e796d6c3f7374796c653d666c6174266c6f676f3d676974687562)](https://github.com/remotemerge/totp-php)[![Sonar Quality](https://camo.githubusercontent.com/e3a13921f506c6475ee8e92e89793569bf6d35fb4de4237a0798772c354cf756/68747470733a2f2f696d672e736869656c64732e696f2f736f6e61722f7175616c6974795f676174652f746f74702d7068702f6d61696e3f7365727665723d6874747073253341253246253246736f6e6172636c6f75642e696f267374796c653d666c6174266c6f676f3d736f6e617271756265636c6f7564266c6f676f436f6c6f723d313236454433266c6162656c3d7175616c697479)](https://sonarcloud.io/summary/overall?id=totp-php&branch=main)[![Sonar Coverage](https://camo.githubusercontent.com/da242523309ee9c805ebbbeeabed6069b88092b1a774d4a5a8506afe5abc1c64/68747470733a2f2f696d672e736869656c64732e696f2f736f6e61722f636f7665726167652f746f74702d7068702f6d61696e3f7365727665723d6874747073253341253246253246736f6e6172636c6f75642e696f267374796c653d666c6174266c6f676f3d736f6e617271756265736572766572266c6f676f436f6c6f723d313236454433)](https://sonarcloud.io/summary/overall?id=totp-php&branch=main)[![Downloads](https://camo.githubusercontent.com/cc6464a73437aea91f9ec737b5a048b1783affb843de33ffa9e98259a6daf50f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f72656d6f74656d657267652f746f74702d7068702e7376673f7374796c653d666c6174266c6162656c3d646f776e6c6f616473)](https://packagist.org/packages/remotemerge/totp-php)[![License](https://camo.githubusercontent.com/48d9f0c0751ae7b1ca1c5f5738cbb722ad2999778fbdce731c00cb2c8f179eee/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f72656d6f74656d657267652f746f74702d706870)](https://github.com/remotemerge/totp-php?tab=MIT-1-ov-file)

[![TOTP PHP Features](public/img/features-v1.png)](public/img/features-v1.png)

**Table of Contents**
---------------------

[](#table-of-contents)

\#TitleDescription1[Why TOTP PHP?](#why-choose-totp-php)Ideal for secure logins, data protection, and enhanced user security.2[Key Features](#key-features)Secure secret generation, multi-algorithm support, QR codes, customization.3[Compatibility](#compatibility)Works seamlessly with all major authenticator apps and RFC-compliant tools.4[Get Started](#get-started-in-minutes)Quick installation via Composer and simple usage examples.5[Basic Usage](#basic-usage)Generate secrets, TOTP codes, verify codes, and create QR code URIs.6[Customization](#customization-options)Change hash algorithms, code length, and time slice duration.7[Advanced Usage](#advanced-usage)Replay protection, secret auditing, discrepancy limits, and QR codes.8[Try with Docker](#try-with-docker)Test locally using Docker for quick setup.9[Try without Docker](#try-with-php)Use PHP's built-in server for lightweight local testing.10[Getting Help](#getting-help)Report bugs, get integration help, or collaborate on projects.11[Contribution](#contribution)Follow coding standards, test code, and submit pull requests.12[Screenshots](#screenshots)Visual demo of the library in action.**Why Choose TOTP PHP?**
------------------------

[](#why-choose-totp-php)

TOTP PHP is a versatile, secure, and reliable TOTP library for PHP that provides easy 2FA integration. This developer-friendly, lightweight, and secure library offers simplicity, performance, and customization for secure login systems, data protection, and enhanced user security. TOTP PHP ensures robust protection with ease of use and high performance, designed for modern PHP developers.

---

**Key Features**
----------------

[](#key-features)

✅ **Secure Secret Generation**Generates cryptographically secure secret keys for TOTP, ensuring maximum security.

✅ **Multi Algorithm Support**Supports **SHA1, SHA256, and SHA512** for HMAC hashing, providing flexibility and compatibility with all major authenticator apps.

✅ **QR Code Integration**Generates standards-compliant **otpauth URIs** for QR code setup in authenticator apps like Google Authenticator, Microsoft Authenticator, Authy, and more.

✅ **Customizable Code Length**Generates TOTP codes with **6 or 8 digits**, configurable based on application requirements.

✅ **Time Slice Configuration**Configurable time slice duration (e.g., **30 or 60 seconds**) to match security requirements.

✅ **Discrepancy Verification**Allows **time slice discrepancy** when verifying TOTP codes, ensuring a smooth user experience. This is especially useful for handling clock drifts.

✅ **Replay Attack Protection**The `verifyCodeOnce()` method prevents reuse of already-accepted codes by tracking the last accepted time slice, eliminating replay attack vectors.

✅ **Secret Security Auditing**The `auditSecret()` method inspects a secret key and returns its decoded byte length, strength rating, and actionable warnings — without throwing exceptions.

✅ **Discrepancy Bounds Enforcement**The discrepancy parameter is validated against a configurable upper bound (default: 10), preventing misconfigured or malicious values from widening the verification window indefinitely.

✅ **Easy Verification**Verifies TOTP codes with a **simple and intuitive API**, making integration straightforward.

✅ **Lightweight and Fast**Built for performance, TOTP PHP is **lightweight** and optimized for speed, ensuring minimal overhead.

✅ **Developer Friendly**Designed with developers in mind, TOTP PHP is **easy to use**, well-documented, and fully tested.

---

**Compatibility**
-----------------

[](#compatibility)

TOTP PHP is built to **universal standards** and works seamlessly with **all major authenticator applications** worldwide. Whether users prefer mobile apps, desktop tools, or hardware tokens, this library ensures flawless compatibility across the entire ecosystem.

### **Supported Authenticator Apps**

[](#supported-authenticator-apps)

📱 **Mobile Authenticators**💻 **Desktop &amp; Hardware**✅ Google Authenticator✅ YubiKey Authenticator✅ Microsoft Authenticator✅ FreeOTP✅ Authy✅ OTP Auth (iOS)✅ Duo Mobile✅ Aegis Authenticator✅ 1Password✅ andOTP✅ LastPass Authenticator✅ Any RFC-compliant tool✅ Bitwarden Authenticator### **Standards Compliance**

[](#standards-compliance)

🔒 **RFC-Compliant Implementation**TOTP PHP follows **RFC 6238** for time-based one-time passwords, validates secrets as uppercase **RFC 4648 Base32** with valid padding, and generates **Key URI Format** compatible `otpauth://` URIs. The test suite includes the RFC 6238 Appendix B vectors for SHA1, SHA256, and SHA512.

---

**Get Started in Minutes**
--------------------------

[](#get-started-in-minutes)

Adding TOTP PHP to a project is quick and easy. The library requires **PHP 8.1** or higher.

### **Installation**

[](#installation)

Install the library via Composer:

```
composer require remotemerge/totp-php
```

---

**Basic Usage**
---------------

[](#basic-usage)

### **Generate a Secret Key**

[](#generate-a-secret-key)

```
use RemoteMerge\Totp\TotpFactory;

// Create a new TOTP instance
$totp = TotpFactory::create();

// Generate a new secret key for the user
$secret = $totp->generateSecret();

// Output the secret key
echo "Generated Secret Key: $secret\n";
```

**Output:**

```
Generated Secret Key: MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y

```

`generateSecret()` creates a 20-byte random secret encoded as uppercase Base32. When importing secrets from another system, use `auditSecret()` to inspect decoded length and formatting before storing them.

### **Generate a TOTP Code**

[](#generate-a-totp-code)

```
use RemoteMerge\Totp\TotpFactory;

// Create a new TOTP instance
$totp = TotpFactory::create();

// Example 20-byte Base32 secret
$secret = 'MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y';

// Generate a TOTP code
$code = $totp->getCode($secret);

echo "Generated TOTP Code: $code\n";
```

**Output:**

```
Generated TOTP Code: 123456

```

### **Verify a TOTP Code**

[](#verify-a-totp-code)

```
use RemoteMerge\Totp\TotpFactory;

// Create a new TOTP instance
$totp = TotpFactory::create();

// Example 20-byte Base32 secret and code
$secret = 'MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y';
$code = '123456';

// Verify the code
$isValid = $totp->verifyCode($secret, $code);

echo $isValid ? "✅ Code is valid!\n" : "❌ Code is invalid!\n";
```

**Output:**

```
✅ Code is valid!

```

### **Generate a QR Code URI**

[](#generate-a-qr-code-uri)

```
use RemoteMerge\Totp\TotpFactory;

// Create a new TOTP instance
$totp = TotpFactory::create();

// Example 20-byte Base32 secret and user information
$secret = 'MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y';
$uri = $totp->generateUri($secret, 'user@example.com', 'YourApp');

echo "QR Code URI: $uri\n";
```

**Output:**

```
QR Code URI: otpauth://totp/YourApp:user%40example.com?secret=MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y&issuer=YourApp&algorithm=SHA1&digits=6&period=30

```

---

**Customization Options**
-------------------------

[](#customization-options)

### **Change the Hash Algorithm**

[](#change-the-hash-algorithm)

By default, TOTP PHP uses **SHA1**. The algorithm can be configured to use **SHA256** or **SHA512**:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

// Configure the algorithm
$totp->configure(['algorithm' => 'SHA256']);

$secret = $totp->generateSecret();
$code = $totp->getCode($secret);

echo "Generated TOTP Code (SHA256): $code\n";
```

### **Change the Code Length**

[](#change-the-code-length)

By default, TOTP PHP generates **6-digit codes**. The length can be configured to **8 digits**:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

// Configure the code length
$totp->configure(['digits' => 8]);

$secret = $totp->generateSecret();
$code = $totp->getCode($secret);

echo "Generated 8-Digit TOTP Code: $code\n";
```

### **Change the Time Slice Duration**

[](#change-the-time-slice-duration)

By default, TOTP PHP uses a **30-second time slice**. The duration can be configured to **60 seconds**:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

// Configure the time slice duration
$totp->configure(['period' => 60]);

$secret = $totp->generateSecret();
$code = $totp->getCode($secret);

echo "Generated TOTP Code (60-second period): $code\n";
```

---

**Advanced Usage**
------------------

[](#advanced-usage)

### **Verify Code with Discrepancy**

[](#verify-code-with-discrepancy)

Handle clock drift by allowing a discrepancy of **±1 time slice**:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

$secret = 'MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y';
$code = '123456';

// Allow discrepancy of 1 time slice
$isValid = $totp->verifyCode($secret, $code, 1);

echo $isValid ? "✅ Code is valid!\n" : "❌ Code is invalid!\n";
```

### **Replay Attack Protection**

[](#replay-attack-protection)

Use `verifyCodeOnce()` to prevent a TOTP code from being accepted more than once. It returns the matched time slice on success (store this value and pass it back on the next login), or `null` if the code is invalid or has already been used:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

$secret = 'MHYPSU6HI7UUMFTQD24XVUUQR7JLKV6Y';
$code = '123456';

// Load the last accepted time slice from persistent storage (e.g. database).
// Use 0 on first login.
$lastAcceptedSlice = (int) $user->getLastTotpSlice();

$newSlice = $totp->verifyCodeOnce($secret, $code, $lastAcceptedSlice);

if ($newSlice === null) {
    echo "❌ Code is invalid or has already been used!\n";
} else {
    // Persist the new slice to block future reuse of this code.
    $user->setLastTotpSlice($newSlice);
    echo "✅ Code accepted!\n";
}
```

### **Secret Security Audit**

[](#secret-security-audit)

Use `auditSecret()` to inspect a secret key before storing or using it. The method never throws — all diagnostics are returned in the result array:

```
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

$secret = 'JBSWY3DPEHPK3PXP';

$audit = $totp->auditSecret($secret);

echo "Decoded length: {$audit['length_bytes']} bytes\n";
echo "Strong secret: " . ($audit['is_strong'] ? 'Yes' : 'No') . "\n";

foreach ($audit['warnings'] as $warning) {
    echo "⚠️  Warning: $warning\n";
}
```

**Output:**

```
Decoded length: 10 bytes
Strong secret: No
⚠️  Warning: Secret is weak (10 bytes); recommend >= 20 bytes for adequate security.

```

### **Configuring the Maximum Discrepancy**

[](#configuring-the-maximum-discrepancy)

By default the discrepancy parameter in `verifyCode()` and `verifyCodeOnce()` is capped at **10**. Pass `max_discrepancy` when creating the instance to tighten or relax this limit:

```
use RemoteMerge\Totp\TotpFactory;

// Restrict the maximum allowed discrepancy to 2 time slices
$totp = TotpFactory::create(['max_discrepancy' => 2]);

$secret = $totp->generateSecret();
$code = $totp->getCode($secret);

// discrepancy of 1 is within the limit — works normally
$isValid = $totp->verifyCode($secret, $code, 1);

// discrepancy of 3 exceeds the limit — throws TotpException
$totp->verifyCode($secret, $code, 3);
```

### **Generate a QR Code Image**

[](#generate-a-qr-code-image)

Generate the `otpauth://` URI on the backend, then render the QR image locally in the browser. Avoid sending TOTP setup URIs to third-party QR image APIs because the URI contains the user's secret.

```
// secret.php
use RemoteMerge\Totp\TotpFactory;

$totp = TotpFactory::create();

$secret = $totp->generateSecret();
$uri = $totp->generateUri($secret, 'user@example.com', 'YourApp');

echo json_encode([
    'secret' => $secret,
    'uri' => $uri,
], JSON_THROW_ON_ERROR);
```

```

  import QRCode from 'https://cdn.jsdelivr.net/npm/qrcode@1.5/+esm';

  const response = await fetch('/secret.php');
  const data = await response.json();

  document.getElementById('qrImage').src = await QRCode.toDataURL(data.uri, {
    errorCorrectionLevel: 'H',
    width: 256,
    margin: 2,
  });

```

---

**Try with Docker**
-------------------

[](#try-with-docker)

Test the TOTP PHP library locally using Docker. This method automatically sets up the environment with all dependencies. Follow these steps:

1. Clone the repository:

    ```
    git clone git@github.com:remotemerge/totp-php.git
    cd totp-php
    ```
2. Start the Docker container:

    ```
    bash start-docker.sh
    ```
3. Access the application at `http://localhost:8080`.
4. (Optional) Access the container shell for development:

    ```
    bash pkg-cli.sh
    ```

---

**Try with PHP**
----------------

[](#try-with-php)

For a lightweight setup, use PHP's built-in server. This method is ideal for quick local testing and doesn't require Docker. Follow these steps:

1. Clone the repository:

    ```
    git clone git@github.com:remotemerge/totp-php.git
    cd totp-php
    ```
2. Install dependencies using Composer:

    ```
    composer install
    ```
3. Start the PHP built-in server:

    ```
    php -S localhost:8080 -t public
    ```
4. Access the application at `http://localhost:8080`.

---

**Getting Help**
----------------

[](#getting-help)

Bugs and feature requests are tracked using GitHub issues and prioritized to ensure the library remains reliable and up to date.

- **Bug Reports**Issues can be reported by [opening an issue](https://github.com/remotemerge/totp-php/issues/new) on GitHub. All issues are addressed diligently to maintain the library's quality.
- **Integration Assistance**For assistance with integration or questions about features, please open a GitHub issue or discussion.

---

**Contribution**
----------------

[](#contribution)

Contributions from the **Open Source community** are highly valued and appreciated. To ensure a smooth and efficient process, contributors should adhere to the following guidelines:

- **Coding Standards**: Code must adhere to [PER Coding Style 3.0](https://www.php-fig.org/per/coding-style/) standards.
- **Testing**: All submitted code must pass relevant tests to maintain the library's reliability.
- **Documentation**: Proper documentation and clean code practices are essential for maintainability.
- **Pull Requests**: Pull requests should be made to the `main` branch.

All contributions are reviewed and appreciated.

**Screenshots**
---------------

[](#screenshots)

[![Screenshot 1](public/img/demo.png)](public/img/demo.png)

###  Health Score

53

—

FairBetter than 96% of packages

Maintenance91

Actively maintained with recent releases

Popularity38

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~72 days

Total

8

Last Release

43d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7168058?v=4)[Weber](/maintainers/sapkotamadan)[@sapkotamadan](https://github.com/sapkotamadan)

---

Top Contributors

[![remotemerge](https://avatars.githubusercontent.com/u/4655731?v=4)](https://github.com/remotemerge "remotemerge (224 commits)")[![Elias-Yona](https://avatars.githubusercontent.com/u/67762511?v=4)](https://github.com/Elias-Yona "Elias-Yona (1 commits)")

---

Tags

2fa2fa-security2factorapi-securityone-time-passwordotp-generatorotp-libraryotp-verificationphp-2faphp-securitytime-based-otptotp-authenticatortotp-generatorweb-securityotptotpsecurityauthAuthentication2faTwo Factor Authenticationtwo-factorhmacone-time-passwordMulti Factor Authenticationphp-securityweb-securityapi-securityphp-2fasecure-authenticationtime-based-otp

###  Code Quality

TestsPHPUnit

Static AnalysisRector

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/remotemerge-totp-php/health.svg)

```
[![Health](https://phpackages.com/badges/remotemerge-totp-php/health.svg)](https://phpackages.com/packages/remotemerge-totp-php)
```

###  Alternatives

[paragonie/multi-factor

Vendor-agnostic two-factor authentication library

142198.6k2](/packages/paragonie-multi-factor)[ellaisys/aws-cognito

Laravel Authentication using AWS Cognito (Web and API)

123256.9k1](/packages/ellaisys-aws-cognito)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
