TOTP: Autentikator 2FA โ€” Cara Kerja dan Membangunnya Sendiri

Kenapa kode 6 digit di Google Authenticator bisa dipercaya, dan bagaimana Anda bisa membangun sistem yang sama tanpa biaya sepeser pun.


๐Ÿงช Coba Demo TOTP Live โ†’ โ€” enroll, scan QR, dan verifikasi langsung di browser. Gratis, tanpa registrasi.


Apa Itu TOTP?

TOTP (Time-based One-Time Password) adalah standar terbuka (RFC 6238) untuk menghasilkan kode sekali pakai yang berubah setiap 30 detik. Inilah yang dipakai Google Authenticator, Authy, dan aplikasi 2FA lainnya.

Contoh nyata di kehidupan sehari-hari:

  • Login ke Google/GitHub โ†’ muncul permintaan "masukkan kode 6 digit"
  • Kode itu diambil dari aplikasi auth di HP Anda
  • Kode berikutnya akan berbeda 30 detik kemudian

Pertanyaannya: dari mana asal kode itu? Ternyata jawabannya sangat sederhana โ€” matematika yang bisa dijalankan siapa pun.


Kenapa 2FA Lebih Aman dari Password Saja?

Password bisa dicuri: phishing, database bocor, keylogger. Tapi untuk menipu 2FA, penyerang harus mendapatkan akses fisik ke HP Anda โ€” dan itu jauh lebih sulit.

TOTP bekerja dengan prinsip:

Secret + Jam = Kode

  • Secret: kombinasi huruf yang hanya diketahui server Anda dan HP pengguna
  • Jam: waktu sekarang, dibagi 30 detik (counter)
  • Kode: hasil perhitungan HMAC dari keduanya

Karena kode dihitung offline di HP dari secret + jam, tidak ada API berbayar, tidak ada server pihak ketiga, dan tidak ada koneksi internet yang dibutuhkan.


Cara Kerja di Balik Layar

Alur TOTP secara teknis:

1. Saat enroll: server menghasilkan secret acak โ†’ dikirim ke HP via QR code
2. Setiap 30 detik:
   counter = floor(timestamp / 30)
   hash   = HMAC-SHA1(secret, counter)    โ† satu-satunya operasi matematika
   kode   = 6 digit pertama dari hash      โ† angka yang Anda lihat
3. Saat verifikasi: server menghitung kode yang sama untuk saat ini
   โ†’ cocok? Berarti yang mengetik memang pemilik HP yang sah

HMAC-SHA1 adalah fungsi hash bawaan PHP โ€” tidak perlu instalasi apapun.


Membangun Autentikator TOTP Sendiri

Kabar baiknya: library TOTP bisa ditulis dalam ~150 baris PHP murni, tanpa composer package, tanpa biaya. Ini prinsip yang saya pakai saat membangunnya untuk sistem SIMRS (verifikasi CPPT dokter):

1. Library Inti (RFC 6238)

<?php
class Totplib {
    private $period = 30;      // interval 30 detik
    private $digits = 6;       // panjang kode
    private $algo   = 'sha1';  // algoritma HMAC

    public function generate_code($secret, $time = null) {
        $time = $time ?? time();
        $counter = intdiv($time, $this->period);

        // Base32 decode secret (format standar QR TOTP)
        $secret_bin = $this->base32_decode($secret);

        // HMAC-SHA1 dari counter
        $hash = hash_hmac($this->algo, pack('N*', 0) . pack('N*', $counter), $secret_bin, true);

        // Dynamic truncation (RFC 4226 bagian 5.3)
        $offset = ord($hash[19]) & 0x0F;
        $code = (ord($hash[$offset]) & 0x7F) << 24
              | (ord($hash[$offset+1]) & 0xFF) << 16
              | (ord($hash[$offset+2]) & 0xFF) << 8
              | (ord($hash[$offset+3]) & 0xFF);

        return str_pad($code % 1000000, $this->digits, '0', STR_PAD_LEFT);
    }

    public function verify_code($secret, $code, $window = 1) {
        // Cek kode sekarang + window ยฑ1 (toleransi beda jam ยฑ30 detik)
        for ($i = -$window; $i <= $window; $i++) {
            $time = time() + ($i * $this->period);
            if (hash_equals($this->generate_code($secret, $time), $code)) {
                return true;
            }
        }
        return false;
    }

    private function base32_decode($s) { /* ... standar RFC 4648 ... */ }
}

2. Enroll: Secret + QR Code

// Generate secret acak 20 byte
$secret = strtoupper(bin2hex(random_bytes(10)));
// Format: "JBSWY3DPEHPK3PXP" (base32, dipindai QR oleh Google Auth)

// URL QR (standar otpauth)
$qr_url = "otpauth://totp/" . urlencode("SIMRS Anda:" . $nik)
        . "?secret=" . $secret
        . "&issuer=" . urlencode("SIMRS Anda");
// Render QR dengan library qrcode โ†’ pengguna scan โ†’ selesai

3. Anti-Replay: Kenapa Kode Tidak Bisa Dipakai Dua Kali

Ini bagian yang sering dilupakan. Tanpa proteksi ini, penyerang yang menangkap kode (misal dari keyboard logger) bisa memakainya lagi. Solusinya: simpan counter terakhir yang berhasil:

// Simpan setelah verifikasi sukses
if ($row['last_counter'] !== null && $counter <= $row['last_counter']) {
    return false;  // kode sudah dipakai sebelumnya โ†’ tolak!
}

Sederhana tapi efektif โ€” setiap kode hanya berlaku sekali.


Checklist Keamanan yang Perlu Diperhatikan

Kalau membangun sendiri, jangan lupa:

  1. hash_equals() untuk membandingkan kode โ€” bukan == (mencegah timing attack)
  2. Secret jangan pernah dikirim via URL yang bisa ter-log โ€” hanya lewat QR/HTTPS
  3. Anti-replay wajib โ€” kode boleh dipakai sekali saja
  4. Secret hanya milik pemiliknya โ€” jangan tampilkan di halaman admin umum
  5. Hapus sekali bersih โ€” kalau user ingin daftar ulang, generate secret BARU (bukan reuse yang lama)

Perbandingan: Bangun Sendiri vs Layanan Berbayar

Aspek Bangun Sendiri Layanan Berbayar
Biaya Rp 0 โ€” library PHP murni Per-signature / langganan bulanan
Ketergantungan Nol โ€” server sendiri Tergantung vendor
Internet 100% offline Butuh API call
Kustomisasi Penuh โ€” alur sesuai kebutuhan Terbatas
Standar RFC 6238 (sama) RFC 6238 (sama)

Untuk kebutuhan akuntabilitas internal (misal: verifikasi siapa yang menyetujui catatan medis), solusi sendiri sudah lebih dari cukup โ€” dan jujur, gratis selamanya.


Kesimpulan

TOTP bukan teknologi ajaib โ€” hanya HMAC + jam. Yang membuatnya aman adalah secret yang rahasia, bukan kompleksitas algoritmanya. Karena itu:

  • โœ… Bangun sendiri: mudah, gratis, sesuai standar
  • โœ… Google Authenticator: aplikasi gratis, kompatibel
  • โœ… 100% offline, tanpa langganan
  • โŒ Tidak perlu layanan berbayar untuk akuntabilitas internal

Satu-satunya "biaya" adalah waktu Anda: ~1 menit per orang untuk enroll sekali di awal. Setelah itu, proteksi 2FA aktif selamanya.


Artikel ini ditulis berdasarkan pengalaman nyata membangun sistem TOTP sendiri untuk verifikasi CPPT di SIMRS menggunakan PHP murni (RFC 6238) โ€” gratis, offline, tanpa pihak ketiga.


๐Ÿงช Ingin langsung mencoba? Buka Demo TOTP Live โ€” enroll, pindai QR, aktifasi, dan uji verifikasi anti-replay langsung di browser Anda. Semua berjalan lokal di server, 100% offline.