Belajar 2FA Authentication - Testing: RFC Test Vectors & E2E Real Device
Episode 16 of 23

Belajar 2FA Authentication - Testing: RFC Test Vectors & E2E Real Device

Episode ini menguji 2FA secara menyeluruh: validasi TOTP terhadap test vector resmi RFC 6238 dengan fake timers, uji clock skew dan window toleransi, serta E2E dengan Google Authenticator sungguhan termasuk skenario negatif kode salah, kedaluwarsa, dan replay.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Fitur 2FA mengatur kriptografi dan waktu — dua hal yang paling sulit diuji secara manual. Episode 16 membahas strategi pengujian yang menyeluruh: unit test dengan test vector resmi RFC 6238, pengujian waktu dengan fake timers, dan E2E dengan Google Authenticator sungguhan.

Mengapa pengujian ini tidak bisa ditunda? Karena bug TOTP muncul paling buruk di produksi — kode yang kadang diterima, kadang tidak, membuat pengguna terkunci dan tiket support melonjak. Kalian akan membangun tiga lapis pengujian yang menangkap masalah ini jauh sebelum pengguna merasakannya.

Tiga lapis itu saling melengkapi, bukan saling menggantikan: unit test membuktikan rumusnya benar, uji waktu membuktikan toleransinya masuk akal, dan E2E membuktikan pengguna nyata bisa melewati alur.

Unit Test dengan Test Vector RFC 6238

Vektor Resmi sebagai Sumber Kebenaran

RFC 6238 memuat tabel test vector: pasangan waktu dan kode yang dijamin benar untuk secret tertentu. Vektor ini adalah tolok ukur — jika library menghasilkan kode yang sama, implementasinya sesuai standar. Secret yang dipakai adalah ASCII "12345678901234567890" yang di-encode Base32.

Uji dengan fake timers dan vektor SHA1 8 digit:

JSUji kode dengan vektor resmi RFC 6238
const { authenticator } = require('otplib');
const SECRET = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';
 
jest.useFakeTimers();
jest.setSystemTime(new Date('1970-01-01T00:00:59.000Z'));
 
test('TOTP cocok dengan vektor RFC 6238', () => {
  authenticator.options = { algorithm: 'SHA1', digits: 8, step: 30 };
  expect(authenticator.generate(SECRET)).toBe('94287082');
});

Waktu 1970-01-01 00:00:59 menghasilkan counter 1, dan vektor RFC 6238 untuk counter 1 dengan SHA1 dan 8 digit adalah 94287082. jest.setSystemTime menggantikan jam sungguhan sehingga pengujian tidak bergantung pada waktu yang sedang berjalan.

Untuk kenyamanan, tetapkan secret ini sebagai konstanta di helper test, sehingga semua file pengujian memakai sumber yang sama. Jika secret berubah di satu tempat tanpa mengubah yang lain, kegagalan test langsung menunjukkan inkonsistensi.

Jangan Hanya Satu Vektor

Satu vektor mengonfirmasi dasar, bukan keseluruhan. Uji beberapa titik: counter 0, counter bernilai besar, digits 6 dan 8, serta algoritma SHA256 dan SHA512 yang juga punya vektor di RFC. Setiap kombinasi menutup cabang kode yang berbeda di dalam library dan memastikan opsi konfigurasi diterjemahkan dengan benar.

Gunakan juga uji round-trip sederhana: generate dengan otplib lalu verify dengan check pada waktu yang sama, untuk memastikan pasangan generate dan verify berjalan konsisten di luar vektor statis.

Menguji Waktu dan Window

Clock Skew

TOTP hidup dan mati di sinkronisasi jam. Uji toleransi dengan memajukan waktu melewati batas step:

JSUji clock skew dalam window toleransi
authenticator.options = { step: 30, window: 1 };
 
jest.setSystemTime(new Date('1970-01-01T00:00:00.000Z'));
const kodeAwal = authenticator.generate(SECRET);
 
jest.setSystemTime(new Date('1970-01-01T00:00:45.000Z'));
const kodeBerikutnya = authenticator.generate(SECRET);
 
expect(authenticator.check(kodeAwal, SECRET)).toBe(true);
expect(authenticator.check(kodeBerikutnya, SECRET)).toBe(true);

Pada detik ke-45, step saat ini adalah 1 sedangkan kodeAwal berasal dari step 0. Dengan window 1, kode lama tetap diterima — persis perilaku yang membuat pengguna dengan jam sedikit terlambat tidak terkunci.

Uji Negatif Waktu

Uji juga sisi gagalnya: kode dari step yang jauh di luar window harus ditolak, dan kode yang sama tidak boleh diterima dua kali (replay). Dua skenario ini adalah yang paling sering lolos dari pengujian manual dan paling berbahaya di produksi — episode 10 membangun mekanisme lastUsedStep yang wajib diuji di sini.

Untuk simulasi jam yang menyimpang, beberapa framework menyediakan helper untuk memajukan waktu sistem di proses test — gunakan dengan hati-hati dan kembalikan jam sebenarnya setelah selesai agar test lain tidak terganggu.

E2E dengan Real Device

Google Authenticator Sungguhan

Unit test membuktikan matematika; E2E membuktikan kompatibilitas. Jalankan aplikasi di HTTPS lokal (episode 13), buka halaman Enable 2FA, dan pindai QR dengan Google Authenticator sungguhan:

Alur uji E2E dengan perangkat nyata
1. Pindai QR dengan Google Authenticator
2. Verifikasi kode pertama di form konfirmasi
3. Logout lalu login ulang
4. Input kode TOTP dari aplikasi
5. Uji recovery code setelah menghapus akun dari aplikasi

Pengujian dengan perangkat nyata menangkap hal yang tidak terlihat di unit test: kompatibilitas pemindaian, format secret yang ditampilkan, dan perilaku aplikasi authenticator pada versi tertentu.

Sebaiknya lakukan uji ini di beberapa perangkat: Android dan iOS memakai versi Google Authenticator yang berbeda, dan perilaku import/export bisa berbeda antar platform.

Skenario Negatif yang Wajib Diuji

Lengkapi dengan skenario negatif: kode salah ketik ditolak, kode kedaluwarsa ditolak, kode yang sama dipakai dua kali ditolak, recovery code terpakai ditolak, dan rate limit memblokir setelah 5 percobaan. Catat hasilnya dalam daftar periksa yang bisa diulang di setiap rilis — ini melindungi dari regresi yang diam-diam masuk bersama perubahan lain.

Otomatiskan skenario ini bila memungkinkan lewat integrasi test, dan simpan output manual sebagai lampiran rilis — bukti uji sering diminta dalam audit.

Penutup

Episode 16 menutup pengujian dengan tiga lapis: unit test terhadap vektor RFC 6238 dengan fake timers, pengujian clock skew dan window toleransi, serta E2E dengan Google Authenticator sungguhan termasuk semua skenario negatif.

Inti yang harus dibawa pulang:

  • Test vector RFC 6238 adalah sumber kebenaran untuk kode TOTP.
  • Gunakan fake timers agar pengujian tidak bergantung pada jam berjalan.
  • Uji lebih dari satu vektor: SHA1, SHA256, digits 6 dan 8.
  • Uji clock skew dalam batas window dan di luarnya.
  • E2E dengan perangkat nyata menangkap masalah kompatibilitas.
  • Uji semua skenario negatif: salah, kedaluwarsa, replay, recovery terpakai.

Di episode 17 selanjutnya kita akan membahas melampaui TOTP: WebAuthn dan passkeys — prinsip FIDO2 yang tahan phishing tanpa shared secret, perbandingan TOTP versus WebAuthn versus SMS, dan strategi menawarkan keduanya sekaligus.

Belajar 2FA Authentication - Testing: RFC Test Vectors & E2E Real Device | Belajar 2FA Authentication