covaleski / otp
一次性密码生成。
v1.1.0
2024-04-21 15:27 UTC
Requires
- covaleski/data-encoding: ^1.0
Requires (Dev)
- laravel/pint: ^1.15
- phpunit/phpunit: ^9.6
README
PHP 实现了RFC 4226和RFC 6238。生成一次性密码。
提供了一个可用的TOTP类,便于与认证器应用程序集成,同时还提供了一个可扩展的HOTP类,用于自定义一次性密码实现。
1 安装
composer require covaleski/otp
2 使用方法
2.1 TOTP
Totp
类可用于以下操作:
- 生成密码;
- 验证接收到的密码;
- 创建用于生成二维码的URI。
2.1.1 创建URI
认证器二维码实际上是作为二维码编码的OTP URI。按照以下步骤创建URI。
use Covaleski\Otp\Totp; // Define some settings. $digits = 6; $issuer = 'Foobar Inc.'; $label = 'Foobar: john@foobar.com'; // Create a secret. $secret = '1234'; // Instantiate the TOTP class and get the URI. $totp = new Totp($digits, $issuer, $label, $secret); $uri = $totp->getUri();
您可以使用您选择的任何库将URI输出为二维码。
2.1.2 生成和验证密码
使用getPassword()
获取当前密码。
use Covaleski\Otp\Totp; // Instantiate the TOPT class. $digits = 6; $totp = new Totp(6, 'Cool LLC', 'Cool: john@cool.com', $secret); // Get the current password. $input = (string) $_POST['code']; $is_valid = $totp->getPassword() === $input; echo 'Your code is ' . ($is_valid ? 'correct!' : 'incorrect!');
2.1.3 自定义
您可以更改生成器的一些参数。以下示例创建了一个TOTP对象,该对象
- 输出8位密码;
- 每15秒更改一次密码;
- 使用1小时的时差计算密码。
use Covaleski\Otp\Totp; // Instantiate and configure. $totp = new Totp(8, $issuer, $label, $secret); $totp ->setStep(15) ->setOffset(3600);
请注意,某些实现可能会忽略或甚至拒绝一个或多个自定义TOTP参数。最兼容的配置(通常是)是每30秒生成6位密码,无时差。
2.2 自定义HOTP实现
您可以扩展Covaleski\Otp\Hotp
来创建您自己的一次性密码实现。
扩展必须提供两个方法:getCounter()
和getUri()
。第一个必须输出当前计数器作为8字节二进制字符串(例如时间计数器),第二个负责提供集成URI。
此外,Hotp
类将执行其余操作,
- 生成HMAC-SHA-1字符串;
- 动态截断HMAC二进制字符串;
- 计算HOTP值并输出所需数量的数字。
请参阅Covaleski\Otp\Totp
类中方法的实现
class Totp extends Hotp { // ...Other class members... /** * Get the current time counter. * * Returns the counter as a 8-byte binary string. */ protected function getCounter(): string { // Get and offset the current UNIX timestamp. $time = time() + $this->offset; // Calculate the number of steps. $counter = floor($time / $this->step); // Format the number as an 8-byte binary string. $counter = dechex($counter); $counter = str_pad($counter, 16, '0', STR_PAD_LEFT); $counter = hex2bin($counter); return $counter; } /** * Get the URI for authentication apps. */ public function getUri(): string { // Encode the secret as base32. $secret = Base32::encode($this->secret); $secret = str_replace('=', '', $secret); // Build URI. return $this->createUri('totp', [ 'secret' => $secret, 'issuer' => $this->issuer, 'algorithm' => 'SHA1', 'digits' => $this->digits, 'period' => $this->step, ]); } // ...Other class members... }
Totp
类依赖于时间来创建其计数器,并在创建URI时将密钥编码为base32字符串。
3 测试
测试使用PHPUnit进行。使用以下命令运行它们。
./vendor/bin/phpunit