MicroPython是否支持pyotp?求轻量设备TOTP程序适配方案
适配MicroPython的TOTP设备实现方案
因为MicroPython环境下没有官方的pyotp库,我们需要手动实现TOTP的核心逻辑,同时适配轻量设备的文件操作、时间处理和清屏行为。以下是完整的适配代码:
完整实现代码
import ujson import uhashlib import utime from ubinascii import b2a_base64, a2b_base64 def hmac_sha1(key, msg): # 实现HMAC-SHA1计算,适配MicroPython的uhashlib block_size = 64 if len(key) > block_size: key = uhashlib.sha1(key).digest() key += b'\x00' * (block_size - len(key)) o_key_pad = bytes((x ^ 0x5c) for x in key) i_key_pad = bytes((x ^ 0x36) for x in key) return uhashlib.sha1(o_key_pad + uhashlib.sha1(i_key_pad + msg).digest()).digest() def hotp(key, counter, digits=6): # 计算HOTP值 counter_bytes = counter.to_bytes(8, 'big') hmac_result = hmac_sha1(key, counter_bytes) offset = hmac_result[-1] & 0x0f binary = ((hmac_result[offset] & 0x7f) << 24) | \ ((hmac_result[offset+1] & 0xff) << 16) | \ ((hmac_result[offset+2] & 0xff) << 8) | \ (hmac_result[offset+3] & 0xff) return str(binary % (10 ** digits)).zfill(digits) def totp(key, time_step=30, digits=6): # 基于当前时间计算TOTP值 current_time = utime.time() counter = current_time // time_step return hotp(a2b_base64(key + '='), counter, digits) # 读取令牌数据 def load_tokens(file_path='/data.json'): try: with open(file_path, 'r') as f: return ujson.load(f) except OSError: # 如果文件不存在,返回空字典(可根据需求调整) return {} def clear_screen(): # 适配终端清屏,替代os.system('clear/cls') print('\033[H\033[J', end='') # 主循环 tokens = load_tokens() while True: clear_screen() for name, token in tokens.items(): print(f"{name}: {totp(token)}") utime.sleep(10)
关键适配说明
- 核心逻辑实现:手动实现了
hmac_sha1、hotp和totp函数,完全基于MicroPython内置的uhashlib和ubinascii模块,无需额外安装库。 - 文件操作:使用
ujson替代标准json模块,文件路径注意适配设备存储(ESP32默认根目录为flash存储,树莓派Zero的MicroPython可根据实际路径调整)。 - 清屏处理:用ANSI转义序列
\033[H\033[J实现跨平台终端清屏,替代依赖系统命令的os.system。 - 时间同步:确保设备时间准确是TOTP正常工作的前提:
- 树莓派Zero:如果使用带系统的MicroPython,可通过系统同步时间;纯MicroPython环境需手动配置NTP。
- ESP32:可在代码开头添加NTP同步逻辑(示例:
import ntptime; ntptime.settime()),需确保设备联网。
data.json格式要求
和你原来的格式完全一致,注意上传到设备的对应路径:
{ "GitHub": "JBSWY3DPEHPK3PXP", "Google": "ABCDEFGHIJKLMNOP", "WeChat": "QRSTUVWXYZ123456" }
内容的提问来源于stack exchange,提问作者Rickyxrc
相关产品推荐
相关产品推荐

