snippets/TOTP-algorithm/Python-TOTP-algorithm.md

1.0 KiB

Implementation of the TOTP algorithm in Python

from hashlib import sha1
from datetime import datetime
from base64 import b32decode

INTERVAL = 30
TOTP_KEY = "BOMY6BV5BWVJEWJ4ZLDYKN3LSIS736B3"

def generate():
    # Pre-process data
    epoch = datetime.now().timestamp()
    msg = int(epoch) // INTERVAL
    bytes_msg = msg.to_bytes(8, byteorder="big")

    key_decoded = b32decode(TOTP_KEY, casefold=True)

    # HMAC-SHA1
    key_pad = key_decoded.ljust(64, b"\0")
    i_key_pad = bytes(x ^ 0x36 for x in key_pad)
    o_key_pad = bytes(x ^ 0x5C for x in key_pad)
    i_key_pad_msg = i_key_pad + bytes_msg
    i_key_pad_msg_hashed = sha1(i_key_pad_msg).digest()
    o_key_pad_msg = o_key_pad + i_key_pad_msg_hashed
    hmac_result = sha1(o_key_pad_msg).digest()

    # TOTP Algorithm
    start = hmac_result[19] & 0xF
    raw_bytes = hmac_result[start:start + 4]
    raw_token = int.from_bytes(raw_bytes, byteorder="big")
    raw_token = raw_token & 0x7F_FF_FF_FF
    token = raw_token % 1_000_000

    print(str(token).rjust(6, "0"))