当前位置:首页 > PHP

php实现TOTP

2026-01-30 03:08:34PHP

TOTP 简介

TOTP(Time-Based One-Time Password)是基于时间的一次性密码算法,常用于双因素认证(2FA)。其核心是结合共享密钥和当前时间戳生成动态密码,通常每30秒更新一次。

实现步骤

安装依赖库 确保已安装 PHP 的 hash_hmacbase64_decode 函数支持。推荐使用 Base32 编码库处理密钥(如 spomky-labs/base32):

composer require spomky-labs/base32

生成共享密钥 使用 Base32 编码生成一个随机密钥:

use Base32\Base32;
$secret = Base32::encode(random_bytes(10)); // 16字符的Base32密钥

计算时间窗口 TOTP 以30秒为一个时间窗口(Unix时间戳除以30取整):

$timestamp = time();
$timeWindow = floor($timestamp / 30);

生成HMAC-SHA1哈希 使用 hash_hmac 生成密钥和时间的哈希:

$hash = hash_hmac('sha1', pack('J', $timeWindow), Base32::decode($secret), true);

动态截断(DT) 取哈希最后一个字节的低4位作为偏移量,从该偏移量开始截取4字节:

$offset = ord(substr($hash, -1)) & 0x0F;
$binary = substr($hash, $offset, 4);

生成6位数字密码 将截取的二进制数据转换为无符号整数,取最后6位:

php实现TOTP

$otp = (unpack('N', $binary)[1] & 0x7FFFFFFF) % 1000000;
$otp = str_pad($otp, 6, '0', STR_PAD_LEFT);

完整代码示例

use Base32\Base32;

function generateTOTP($secret, $timestamp = null) {
    $timestamp = $timestamp ?? time();
    $timeWindow = floor($timestamp / 30);
    $binarySecret = Base32::decode($secret);

    $hash = hash_hmac('sha1', pack('J', $timeWindow), $binarySecret, true);
    $offset = ord(substr($hash, -1)) & 0x0F;
    $binary = substr($hash, $offset, 4);

    $otp = (unpack('N', $binary)[1] & 0x7FFFFFFF) % 1000000;
    return str_pad($otp, 6, '0', STR_PAD_LEFT);
}

// 使用示例
$secret = Base32::encode(random_bytes(10));
$otp = generateTOTP($secret);
echo "TOTP: $otp (Secret: $secret)";

验证注意事项

  • 时间同步:服务器和客户端时间需同步(NTP协议推荐)。
  • 容错窗口:验证时可检查前后1-2个时间窗口的密码以应对时钟偏差。
  • 密钥存储:共享密钥需安全存储(如加密数据库)。

通过上述步骤可实现符合 RFC 6238 标准的 TOTP 生成器。

标签: phpTOTP
分享给朋友:

相关文章

php实现递归

php实现递归

递归的基本概念 递归是一种函数调用自身的技术,适用于解决可以分解为相同子问题的问题。在PHP中,递归需要明确的终止条件(基线条件),否则会导致无限循环。 递归实现阶乘 阶乘是经典的递归案例,n! =…

php实现异步

php实现异步

PHP 实现异步的方法 PHP 本身是同步执行的脚本语言,但可以通过以下方法模拟异步操作或实现异步效果: 使用多进程(pcntl_fork) 通过 pcntl_fork 创建子进程实现异步,适用于…

php实现短信验证

php实现短信验证

PHP实现短信验证的步骤 选择合适的短信服务提供商 国内常见的短信服务提供商包括阿里云短信、腾讯云短信、云片等。注册账号并获取API密钥和签名模板是第一步。这些平台通常提供详细的开发文档和SDK。…

php 实现锁

php 实现锁

PHP 实现锁的常见方法 文件锁(flock) 利用 flock 函数对文件进行独占锁定,适用于单机环境。 $fp = fopen("lockfile.lock", "w+"); if (flock…

php实现秒杀

php实现秒杀

PHP实现秒杀功能的关键技术 秒杀系统需要解决高并发、数据一致性、系统稳定性等问题。以下是PHP实现秒杀功能的核心技术方案: 数据库优化 使用InnoDB引擎的行级锁和事务特性,确保数据一致性。商品…

php实现单例模式

php实现单例模式

单例模式的概念 单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于数据库连接、日志记录器等需要全局唯一实例的场景。 PHP实现单例模式的关键步骤 私有化构造函…