TOTP (RFC 6238) là HOTP với bộ đếm lấy từ thời gian.
- Server và ứng dụng xác thực chia sẻ một secret ngẫu nhiên (mã hoá base32, thường trao qua QR code).
- Mã 6 chữ số được tính:
T = floor((now - T0) / X) // X = 30s time step
code = truncate(HMAC-SHA1(secret, T)) mod 10^6Hai bên không trao đổi gì thêm — thiết bị hoạt động hoàn toàn offline, đó là lý do TOTP an toàn hơn OTP qua SMS (SMS bị SIM swap và chặn tin nhắn).
Những điểm bắt buộc khi cài đặt:
- Chấp nhận lệch múi thời gian ±1 bước (thường ±30s) cho đồng hồ lệch, không mở rộng hơn.
- Chống dùng lại: lưu bước thời gian gần nhất đã dùng thành công, từ chối cùng một mã lần thứ hai — nếu không, kẻ đọc lén mã trong 30 giây vẫn dùng được.
- Giới hạn tần suất trên bước nhập mã, vì không gian chỉ có 10^6 giá trị.
- Secret phải mã hoá khi lưu (không phải hash — server cần giá trị gốc để tính lại), khoá nằm ở secret store.
- Bắt user xác nhận một mã hợp lệ trước khi bật MFA, tránh khoá chính họ ra ngoài.
Backup code: sinh 8-10 mã ngẫu nhiên đủ entropy, hiển thị đúng một lần khi bật MFA. Trong DB chúng là thông tin xác thực, phải hash như mật khẩu (dùng cùng hàm hash chậm), mỗi mã chỉ dùng một lần rồi vô hiệu. Cho phép user sinh lại bộ mới — thao tác đó phải huỷ toàn bộ bộ cũ.