TOTP(基于时间的一次性口令)简析 python实现

OTP 全称叫One-timePassword,也称动态口令,是根据专门的算法每隔60秒生成一个与时间相关的、不可预测的随机数字组合,每个口令只能使用一次,每天可以产生43200个密码。

OTP有3中形式,分别为时间同步(TOTP),事件同步,挑战/应答。

下面就来简单介绍下TOTP。

TOTP -Time-based One-time Password Algorithm is an extension of the HMAC-based OneTime Password algorithm HOTP to support a time based moving factor(TOTP基于时间的一次性密码算法是支持时间作为动态因素基于HMAC一次性密码算法的扩展)。

HMAC -Hash-based Message Authentication Code。

相关文档:

RFC 4226 - HOTP: An HMAC-BasedOne-Time Password Algorithm

(http://tools.ietf.org/html/rfc4226)

RFC 6238 - TOTP: Time-Based One-TimePassword Algorithm

(http://tools.ietf.org/html/rfc6238)

原理图如下:


要求:

1)        令牌与服务器之间必须时钟同步;

2)        令牌与服务器之间必须共享密钥;

3)        令牌与服务器之间必须使用相同的时间步长

 

算法:

TOTP =Truncate(HMAC-SHA-1(K, (T - T0) / X))

1)        K 共享密钥(令牌种子)

2)        T 是一个整数,代表当前时间(以UTC时间为标准)

3)        T0 是一个整数,代表一个时间点,一般为0

4)        X 口令变化周期,单位为秒,30秒或者60秒

5)        Truncate  HAMC算法得出的位值数比较多,不方面输入,因此需要截断成一组不太长十进制数(例如6位数)

 

RFC 6238文档中有一个java语言示例程序,我这里写了一个python版本的,代码如下:

 

__author__ ='juxuan'

import
hmac
import hashlib
import time
import datetime

class TOTP(object):
   
def __init__(self):
       
self.DIGITS_POWER = [1,10,100,1000,10000,100000,1000000,10000000,100000000 ];

   
def hmac_sha(self, key, msg,crypto):
       
myhmac = hmac.new(key,msg,crypto)
        return myhmac.hexdigest()

   
def generateTOTP(self, key, msg,length, crypto):
       
hash = self.hmac_sha(key,msg, crypto)
       
bytes_hash = [ hash[i:i+2]foriinrange(0,len(hash),2) ]
       
offset = int(bytes_hash[len(bytes_hash)-1],16) & 0xf
       
binary = ((int(bytes_hash[offset],16) &0x7f) << 24) \
               
| ((int(bytes_hash[offset+1],16) &0xff) << 16) \
               
| ((int(bytes_hash[offset+2],16) &0xff) << 8) \
               
| (int(bytes_hash[offset+3],16) &0xff)

       
otp = binary % self.DIGITS_POWER[length]
       
result = str(otp)
       
while len(result) <length:
           
result = "0" + result

       
return result

if __name__ =="__main__":
   
#seed for HMAC_SHA1
   
seed_sha1   = "3132333435363738393031323334353637383930"
   
#seed forHMAC_SHA256
   
seed_sha256 = "3132333435363738393031323334353637383930"\
                 
"313233343536373839303132"
   
#seed forHAMC_SHA512
   
seed_sha512 = "3132333435363738393031323334353637383930"\
                 
"3132333435363738393031323334353637383930"\
             
    "3132333435363738393031323334353637383930"\
                 
"31323334"

   
totp = TOTP();
   
T0 = 0
   
= 60
   
testTimes = [59L,1111111109L,1111111111L, 1234567890L,2000000000L,20000000000L]
   
for iinrange(len(testTimes)):
       
T = (testTimes[i] - T0) / X
        steps = str(T).upper()
       
while len(steps) <16:
           
steps = "0" + steps
       
print "utcTime:"+datetime.datetime.strftime(datetime.datetime.utcfromtimestamp(testTimes[i]),"%Y-%m-%d%H:%M:%S")
 
      print "steps :"+ steps
       
print "SHA   :"+totp.generateTOTP(seed_sha1,   steps, 6, hashlib.sha1)
       
print "SHA256:"+ totp.generateTOTP(seed_sha256, steps,6, hashlib.sha256)
       
print "SHA512:"+ totp.generateTOTP(seed_sha512, steps,6, hashlib.sha512)+"\n"

 

结果如下:

utcTime:1970-01-01 00:00:59

steps  :0000000000000001

SHA    :807215

SHA256 :496488

SHA512 :397631

 

utcTime:2005-03-18 01:58:29

steps  :0000000037037036

SHA    :650743

SHA256 :694729

SHA512 :774782

 

utcTime:2005-03-18 01:58:31

steps  :0000000037037037

SHA    :839043

SHA256 :239243

SHA512 :264185

 

utcTime:2009-02-13 23:31:30

steps  :0000000041152263

SHA    :403899

SHA256 :384578

SHA512 :383107

 

utcTime:2033-05-18 03:33:20

steps  :0000000066666666

SHA    :453673

SHA256 :246989

SHA512 :381445

 

utcTime:2603-10-11 11:33:20

steps  :0000000666666666

SHA    :452866

SHA256 :271026

SHA512 :442876


  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值