Latihan 1 dari materi 2FA dengan TOTP di Auth — praktek dengan editor kode interaktif, test case otomatis, dan hint terpandu. Langsung jalan di browser.
Latihan ini menghitung TOTP asli (RFC 6238). Kode awal sudah punya hmacSha1(kunci, pesan): HMAC-SHA1 di JavaScript biasa, tanpa await. Ia menerima dua array byte (angka 0 sampai 255) dan mengembalikan 20 byte, sama dengan crypto.subtle.sign. Jangan ubah sha1 dan hmacSha1.
generateTotp(secret, timestamp), dengan secret berupa array byte dan timestamp dalam detik:
- Hitung counter:
Math.floor(timestamp / 30).
- Tulis counter sebagai 8 byte big-endian (byte paling besar dulu), lalu
mac = hmacSha1(secret, ke-8 byte itu).
- Dynamic truncation:
offset = mac[19] & 0x0f, ambil 4 byte mulai mac[offset], dan buang bit teratas byte pertamanya (& 0x7f).
- Kembalikan angka itu
% 1000000 sebagai string 6 digit, dengan nol di depan: String(angka % 1000000).padStart(6, "0").
verifyTotp(secret, code, timestamp): buat ulang kode untuk timestamp - 30, timestamp, dan timestamp + 30. Kembalikan true kalau code sama dengan salah satunya, false kalau gak ada yang sama.
secret (secret uji RFC 6238, teks 12345678901234567890 sebagai 20 byte) dan empat console.log di kode awal sudah ada, biarkan. Output-nya harus persis empat baris ini, berurutan:
287082 (T = 59, vektor uji RFC 94287082 dalam 6 digit)
005924 (T = 1234567890, dari 89005924, nol di depannya tetap ada)
true (kode dari 25 detik lalu masih diterima, satu langkah di belakang)
false ("000000" ditolak)
Dicek juga dengan vektor RFC lain: T = 1111111111 jadi "050471" dan T = 20000000000 jadi "353130". Kode untuk 30 detik ke depan diterima tapi 90 detik ke depan ditolak, dan kode dari secret lain ditolak.