相关算法
- HOTP(HMAC-based One-Time Password,基于HMAC的一次性口令)
- TOTP(Time-Based One-Time Password,基于时间的一次性口令)
- HMAC(Hash-based message authentication code,基于散列函数的消息认证码算法)
HMAC
- 算法公式 HMAC(K, m) = H((K’ xor opad) || H ((K’ xor ipad) || m))
- H 散列函数
- K 共享密钥
- K’ 通过K(密钥)计算所得(当散列函数是SHA-1, MD5, RIPEMD-128/160,K’大小为64字节不足后面填充0)
- xor 异或
- opad 外层HASH填充值,0x5c5c5c….长度与K’相当
- ipad 内层HASH填充值,0x363636….长度与K’相当
- m 一个消息输入
- || 表示连接
- 简化理解 sha1(opad.sha1(ipad.m))
- 计算结果 根据所选散列函数变动,sha1为例会得到一个20字节40位的16进制
- PHP自带 hash_hmac ( string
algo,string
data , string
key[,bool
raw_output = false ] )
- 代码示例
function my_hash($algo, $key, $msg) {
$blocksize = '64';
if (strlen($key) > $blocksize)
$key = hash($algo, $key);
if (strlen($key) < $blocksize)
$key = str_pad($key, $blocksize, chr(0x00));
$o_pad = str_repeat(chr(0x5c), $blocksize) ^ $key;
$i_pad = str_repeat(chr(0x36), $blocksize) ^ $key;
return hash($algo, $o_pad. hash($algo, $i_pad. $msg, true));
}
HOTP
- 算法公式 HOTP(K,C) = (Truncate(HMAC(K,C)) & 0x7FFFFFFF) mod 10d
- C 计数器,对应HMAC中的m
- & 与
- T HMAC sha1后得到的结果太长,经过Truncate处理后我会得到一个32bit的无附号整数
- mod 取余,与10的d次方模运算得到d位的一个数字口令
- Truncate代码示例
function truncate($hash) {
$offset = ord($hash[19]) & 0xf;
return (
((ord($hash[$offset+0]) & 0x7f) << 24 ) |
((ord($hash[$offset+1]) & 0xff) << 16 ) |
((ord($hash[$offset+2]) & 0xff) << 8 ) |
(ord($hash[$offset+3]) & 0xff)
) % pow('10', '6');
}
TOTP
- 算法公式 TOTP = HOTP(K, TC)
- TC floor((unixtime(now) − unixtime(T0)) / TS)
- T0 开始计算的时间步长
- TS 时间步长,默认30出于安全与考虑不宜过大
- 代码片断
function totp($secretKey, $f2, $len=6) {
$hash = hash_hmac ('sha1', $data, $key, true);
return str_pad(self::truncateHash($hash), $len, '0', STR_PAD_LEFT);
}
关键点
相关资料