# OTP简介

> 作者：James Zhu (<fatindeed@hotmail.com>)
>
> 创建日期：2018-05-02

## 引言

**OTP**是*One-Time Password*的简写，表示一次性密码。

**HOTP**是*HMAC-based One-Time Password*的简写，表示基于HMAC算法加密的一次性密码。

是事件同步，通过某一特定的事件次序及相同的种子值作为输入，通过HASH算法运算出一致的密码。

**TOTP**是*Time-based One-Time Password*的简写，表示基于时间戳算法的一次性密码。

是时间同步，基于客户端的动态口令和动态口令验证服务器的时间比对，一般每30秒产生一个新口令，要求客户端和服务器能够十分精确的保持正确的时钟，客户端和服务端基于时间计算的动态口令才能一致。

## 应用场景

国外主流网站基本都支持TOTP，又称两步验证、多因子验证，如Google/Facebook/Twitter/Amazon/Dropbox/GitHub/Microsoft等等。有了OTP的保护，即便账户用最简单的密码，黑客仍然难以登录，从而极大地提升了账号的安全级别。

PS：原先我使用**Google Authenticator**来存储所有站点的OTP信息，但是在设备数据迁移时，这部分数据现已无法迁移（可能是加密的原因？）。所以，现在我改用了**Authy**，据说它的数据是保存在云端的，可以避免因设备问题导致的数据丢失。

## Wuxing2示例

Wuxing2框架中已支持OTP，直接使用`Wuxing\Vendor\Otp`即可。

生成OTP示例代码：

```php
$secret = 'Guan@itong';
$otp = new Wuxing\Vendor\Otp;
echo $otp->totp($secret);
```

```bash
/ # php demo.php
477756
```

校验OTP示例代码：

```php
$secret = 'Guan@itong';
$correct = '477756';
$incorrect = '123456';
$otp = new Wuxing\Vendor\Otp;
$result1 = $otp->checkTotp($secret, $correct);
var_dump($result1);
$result2 = $otp->checkTotp($secret, $incorrect);
var_dump($result2);
```

```bash
/ # php demo.php
bool(true)
bool(false)
```

## 参考资料

* [RFC 4226](https://tools.ietf.org/html/rfc4226) One-Time Password and HMAC-based One-Time Password.
* [RFC 6238](https://tools.ietf.org/html/rfc6238) Time-based One-Time Password.
* [RFC 2104](https://tools.ietf.org/html/rfc2104) HMAC Keyed-Hashing for Message Authentication.
* [otp](https://github.com/ChristianRiesen/otp) by ChristianRiesen(Wuxing2框架用的这个)
* [otphp](https://github.com/lelag/otphp) by lelag
* [otphp](https://github.com/Spomky-Labs/otphp) by Spomky-Labs
