我正在使用pyotp。但它有时会在生产中失败。为了复制它,我写了下面的测试:
import pyotp
from time import sleep
key = pyotp.random_base32()
for i in range(10):
otp = pyotp.TOTP(key).now()
sleep(5)
print pyotp.TOTP(key).verify(otp)
示例输出为:
True
False
True
True
True
True
True
False
True
True
我无法调试这里出现的问题,因为它可以工作8/10次。为什么它在2/10失败?
谢谢,
答案 0 :(得分:4)
我不熟悉pyotp
,但是浏览through the code,我遇到了这个问题:
def timecode(self, for_time):
i = time.mktime(for_time.timetuple())
print(i, i/self.interval)
return int(i / self.interval)
timecode
用于比较不同的“otp”并查看它们是否相同; interval
的默认值为30。
可能这个想法是在30秒内,哈希导致相同的结果。不幸的是,编码的方式似乎不起作用:它需要一些绝对的时间(好吧,w.r.t。1970),并将其切成30秒的间隔。 timecode
的结果是自1970年以来30秒的间隔量。当然,一旦时钟已经过*:00
或*:30
,新的30秒间隔开始并且出现不匹配。睡眠时间为5秒,10次试验,你的程序需要50秒,所以几乎 2倍于30秒的界限;因此,当四舍五入为整数值时,将其中的2分(将睡眠时间增加到6秒,对于更大的样本,它将恰好为10分中的2分)。
正如我所提到的,我不知道pyotp
,但看起来这不是预期的,它应该是一个被比较的间隔(datetime.timedelta
可以帮助到这里)。我刚刚注意到your bug report,所以请随意提供这个SO答案的链接。
与此同时,也许你应该避免TOTP
并使用另一个班级;或根据您的需要设置一个令人难以置信的长间隔(例如TOTP(key, interval=315360000)
,即10年)。