---
title: 'TOTP: Cara Kerja Autentikator 2FA dan Membangunnya Sendiri (Gratis, Murni PHP)'
url: 'https://gretha.my.id/site/blog/totp'
markdown: 'https://gretha.my.id/site/blog/totp.md'
date: '2026-10-04'
description: '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 regist…'
---

# 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 →](https://gretha.my.id/totp/)** — 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
<?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

```php
// 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**:

```php
// 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](https://gretha.my.id/totp/) — enroll, pindai QR, aktifasi, dan uji verifikasi anti-replay langsung di browser Anda. Semua berjalan lokal di server, 100% offline.

---

## Navigation

- Parent: [Blog](https://gretha.my.id/site/blog.md)
- Next: [Topologi Jaringan Interaktif: Visualisasi Infrastruktur IT dengan OpenClaw](https://gretha.my.id/site/blog/topologi-jaringan-interaktif.md)
