You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TOTP算法生成OTP时而正确时而错误的原因及修正方案

问题原因与修正方案

问题原因

  1. 未遵循TOTP规范的掩码要求
    RFC 6238(TOTP标准)明确规定,从HMAC结果中提取的32位整数需要与0x7FFFFFFF进行按位与运算,清除最高位以避免有符号/无符号整数处理差异导致的结果偏差。你的代码缺少这一步,当提取的32位整数最高位为1时,生成的OTP会与遵循规范的第三方工具结果不一致,这就是“有时正确有时错误”的核心原因。

  2. 主循环时间处理存在误差
    通过time.sleep(wait_time)后调用int(time.time())获取时间,可能因系统调度延迟导致实际时间跨到下一个时间步,偶尔生成不属于当前显示周期的OTP,进一步加剧结果不一致的情况。

修正后的代码

import hmac
import hashlib
import struct
import time
import base64

def generate_totp(secret, time_step=30, digits=6, current_time=None):
    if current_time is None:
        current_time = int(time.time())
    # 计算时间步(TOTP的核心时间窗口)
    time_window = current_time // time_step
    time_bytes = struct.pack('>Q', time_window)

    # 解码Base32密钥
    secret = base64.b32decode(secret, casefold=True)
    # 计算HMAC-SHA1
    hmac_result = hmac.new(secret, time_bytes, hashlib.sha1).digest()
    
    # 获取偏移量
    offset = hmac_result[-1] & 0xF
    truncated_hash = hmac_result[offset : offset + 4]
    
    # 解压为无符号整数,并添加掩码(符合RFC 6238要求)
    otp = struct.unpack('>I', truncated_hash)[0]
    otp = otp & 0x7FFFFFFF  # 关键修复:清除最高位
    
    # 生成指定位数的OTP
    otp = otp % (10 ** digits)
    otp_str = str(otp).zfill(digits)
    
    return otp_str, time_window

def get_time_until_next_step(time_step=30):
    current_time = int(time.time())
    wait_time = time_step - (current_time % time_step)
    # 返回等待时间和下一个时间步的起始时间
    next_window_start = current_time + wait_time
    return wait_time, next_window_start

# Example Usage:
if __name__ == "__main__":
    secret_key = "2FASTEST"

    while True:
        wait_time, next_window_time = get_time_until_next_step()
        time.sleep(wait_time)
        # 使用预计算的时间步起始时间,避免sleep延迟误差
        current_totp, current_window = generate_totp(secret_key, current_time=next_window_time)
        print(f"Generated TOTP: {current_totp}")

关键修改说明

  1. 添加掩码运算:新增otp = otp & 0x7FFFFFFF,严格遵循RFC 6238规范,确保生成的OTP与第三方工具完全一致。
  2. 优化时间步计算:get_time_until_next_step返回下一个时间步的起始时间,直接用该时间调用generate_totp,避免sleep延迟导致的时间偏差,保证每次生成的OTP都对应正确的时间窗口。

内容的提问来源于stack exchange,提问作者Abhishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:07:33