基于时间的一次密码TOTP

7 篇文章 0 订阅

相关算法


  • 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);

    }

关键点


  • 密钥共享
  • 时间戳/计数器同步与混淆

相关资料


  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值