Langsung ke konten
AFM Studio
  • Halaman

    AFM Studio
  • Karya
  • Lab
  • Tentang
  • CV
  • Kontak
  • Proyek

    AksaraPerpustakaan pengetahuan Otorita IKN yang bisa dicari, dengan server memeriksa akses setiap pembaca di tiga tingkat
  • Daily TaqwaSistem presensi salat anti-manipulasi untuk ~2.000 pegawai OIKN di Masjid Negara IKN
  • Lantara v2Mesin perizinan Otorita IKN tempat administrator menambah jenis izin baru dari layar, tanpa developer
  • eKiosk IKNDua ruang kendali untuk Nusantara: konten kios dan pelacakan bus live dengan estimasi kedatangan yang menilai dirinya sendiri
  • E-Monev IKNPlatform pemantauan pembangunan Nusantara selama 23 tahun, melacak progres triwulan setiap unit terhadap 24 KPI
  • JDIH OIKNPortal dokumen hukum publik OIKN, dengan alur penerbitan terkendali dan ringkasan AI yang tidak pernah keluar dari server
  • Jejak PenanamanAplikasi absen acara penanaman pohon IKN yang membuktikan peserta hadir di lokasi lewat selfie ber-geofence
  • Dashboard SAKTIPipeline malam dan dashboard yang menggantikan unduhan anggaran manual di keenam satker OIKN
  • DoseRxKalkulator dosis untuk 127 obat yang membulatkan dosis ke tablet dan sirup yang dijual apotek Indonesia
  • CubiqPelatih speedcubing dengan timer setara kompetisi dan solver buatan sendiri untuk 8 puzzle utama
  • ScimotionPerpustakaan sains interaktif berisi 86 artikel, masing-masing dijelaskan bersama animasi yang bisa dikendalikan pembaca
  • WA Daily Scrum BotBot WhatsApp yang menagih laporan standup tim 14 orang dan menandai tugas yang macet berhari-hari

↑ ↓ untuk berpindah · Enter untuk membuka · Esc untuk menutup

Oracle

Demo edukasi yang membaca pesan terenkripsi tanpa kunci, hanya dari jawaban ya atau tidak sebuah server

Tangkapan layar
panggilan oracle untuk memulihkan satu blok
~2.000
komponen kriptografi ditulis dari nol
5
API jaringan di aplikasi hasil build
0
dependensi runtime, React dan renderer-nya
2
Di halaman ini

Masalahnya

Banyak orang, termasuk engineer, percaya bahwa "sudah dienkripsi dengan AES" berarti pesannya aman. Kenyataannya tidak begitu. Serangan yang sudah lama didokumentasikan, padding oracle, bisa memulihkan seluruh pesan terenkripsi tanpa membobol cipher-nya. Serangan ini hanya butuh server yang memberi tahu apakah padding sebuah pesan valid. Satu jawaban ya atau tidak, ditanyakan sekitar 2.000 kali per blok, sudah cukup untuk menyusun ulang teksnya.

Penjelasan tentang serangan ini ada di puluhan tempat, tapi jarang mengubah keyakinan orang. Satu halaman aljabar tidak membuat pembaca merasa bahwa AES-nya tidak relevan. Kebanyakan animasi yang ada juga melewatkan pengecekan positif palsu yang dibutuhkan serangan ini. Banyak pula yang diam-diam menyimpan jawabannya di sebuah variabel lalu memutarnya kembali.

Saya membuat Oracle untuk engineer yang perlu memahami kenapa enkripsi terautentikasi itu ada, untuk pengajar keamanan yang butuh demo langsung, dan untuk siapa pun yang ingin menilai apakah saya bisa mengimplementasikan kriptografi dengan benar.

Ini demo edukasi, bukan alat serangan. Aplikasinya tidak punya kode jaringan sama sekali. Sebuah tes memindai bundle hasil build dan menggagalkan build kalau ada API jaringan di dalamnya, jadi ketidakmampuannya menyerang server sungguhan adalah sifat dari build itu sendiri.

Yang saya bangun

Rahasianya saya kunci di tempat yang tak terjangkau layar

Satu modul membuat kunci, pesan, dan blok awal, mengenkripsinya, lalu hanya menyerahkan empat hal: teks terenkripsi, blok awal, oracle ya-atau-tidak, dan penghitung panggilan. Kunci dan pesannya tidak pernah keluar dari modul itu. Jadi saat huruf yang dipulihkan muncul di layar, huruf itu memang hasil serangan. Sebuah tes menyimpan pesan yang sudah diketahui di ruang tertutupnya sendiri, menjalankan serangan asli, lalu mencocokkan byte hasilnya. Aplikasi ini membuktikan bahwa ia tidak curang.

Oracle hanya menjawab satu bit

Oracle menerima pesan terenkripsi dan mengembalikan benar atau salah. Tidak ada detail error, tidak ada info waktu, tidak ada petunjuk byte mana yang gagal. Jawaban yang lebih kaya akan membuat serangannya curang dan tidak mencerminkan apa yang dilihat penyerang sungguhan. Jadi serangannya bekerja dari satu bit, sama seperti aslinya.

Pengecekan positif palsu saya bangun, dan pembaca boleh mematikannya

Saat memulihkan byte terakhir sebuah blok, serangan yang naif bisa menerima kecocokan kebetulan dan mencatat byte yang salah. Semua byte sesudahnya ikut rusak. Perbaikannya adalah mengubah byte sebelumnya lalu bertanya lagi. Saya mengimplementasikannya dan menganimasikannya sebagai langkah tersendiri. Pembaca bisa mematikannya dan melihat pemulihannya rusak. Sebuah tes memastikan versi naif memang gagal pada pesan yang dibuat untuk memicunya.

Serangan dijalankan sekali, lalu rekamannya diputar ulang

Mesin serangannya tidak memuat kode antarmuka dan tidak memakai jam. Seluruh serangan selesai dalam hitungan milidetik dan merekam setiap tebakan, setiap putusan oracle, setiap pengecekan ulang, dan hitungan di balik setiap byte. Layar hanya menampilkan satu titik di rekaman itu. Menggeser maju-mundur tidak memakan biaya, kecepatan animasi lepas dari perhitungan, dan setiap momen bisa dibagikan sebagai tautan.

Kriptografinya saya tulis sendiri

AES-128, SHA-256, HMAC, mode CBC, dan padding PKCS7 semuanya kode saya sendiri, dicek dengan vektor uji resmi. Dependensi runtime-nya hanya React dan renderer DOM-nya. Rencana awal memakai modul AES yang sudah dikompilasi. Saya membatalkannya karena kode tulisan sendiri tidak butuh file biner untuk diaudit dan tidak butuh pengecualian dari aturan tanpa jaringan.

Hasilnya

Oracle sudah live dan terbuka untuk umum. Tampilan utamanya adalah tumpukan byte empat baris: yang dikirim penyerang, padding yang dinilai oracle, blok tengah, dan teks hasil pemulihan yang terisi dari kanan ke kiri dengan warna emas. Sebuah sakelar menukar AES asli dengan cipher mainan yang diberi label jelas, dan serangannya memulihkan teks yang sama dengan biaya yang sama. Kalau encrypt-then-MAC dinyalakan, setiap pesan palsu gagal sebelum didekripsi, sehingga warna emas tidak pernah muncul.

Mode kedua mengubah "user=guest" menjadi "user=admin" di pesan terenkripsi tanpa kunci. Pemulihan butuh sekitar 2.000 panggilan oracle per blok, sesuai rata-rata teoretisnya. Saya membangunnya dalam tujuh hari pada September 2026.

Di balik layarDetail teknis untuk engineer
  • src/engine/secret.ts mengembalikan AttackTarget (ciphertext, IV, oracle, penghitung panggilan). Tipe ini tidak punya field key atau plaintext, dan index.ts di engine hanya mengekspor permukaan untuk serangan. tests/view-blindness.test.ts menjalankan serangan terhadap plaintext yang disimpan di closure milik tes.
  • type Oracle = (ciphertext: Uint8Array) => boolean.
  • Disambiguasi: kalau plaintext berakhir dengan 0x02, … 02 02 hasil rekayasa juga padding yang valid. Serangan mengubah byte kedua dari belakang lalu bertanya ulang. tests/disambiguation.test.ts memastikan jalur naif gagal pada plaintext yang berakhir 0x02. Sakelarnya ?dis=0.
  • Engine-nya murni dan sinkron, tanpa import apa pun, bahkan Date. PRNG dengan seed (src/engine/rng.ts) membuat setiap sesi bisa diulang dari URL; posisi dari tautan lama dijepit ke timeline yang dibangun.
  • AES-128 sekitar 230 baris (src/engine/aes.ts), dikunci dengan vektor uji FIPS-197, sekitar 7,5 KB kode sumber. PRD awalnya meminta AES teraudit yang dikompilasi ke WebAssembly.
  • CI menjalankan typecheck, lint, test, build, lalu grep yang gagal kalau fetch, XMLHttpRequest, WebSocket, atau sendBeacon muncul di bundle, baru kemudian deploy ke GitHub Pages.
  • Tumpukan awalnya tiga baris dan mendapat baris keempat (padding yang sebenarnya dinilai oracle) di tengah pengerjaan. Grafik batang di panel cipher dibuang dan diganti dua angka.
  • Perbaikan aksesibilitas: pintasan Space memblokir Space di setiap tombol (WCAG 2.1.1); tablist tanpa tabpanel diganti tombol dengan aria-pressed (WCAG 4.1.2); pintasan satu huruf f/r dihapus (WCAG 2.1.4). Satu-satunya animasi SMIL, yang lolos dari pengaturan reduced motion, dibuang. Kontras minimal 4,5:1, ekspor hex/tabel untuk setiap byte yang dipulihkan.
  • State memakai React context dan reducer buatan sendiri; animasi satu loop requestAnimationFrame; CSS polos (~2.080 baris).
  • Sekitar 128 panggilan oracle per byte. Ukuran halaman ~73 KB gzip dari anggaran 250 KB.
  • 43 tes di 11 file. ~3.560 baris TypeScript. 65 commit di main (68 di semua ref), 5 sampai 11 September 2026.

Tangkapan layar

Beranda
The Interrogator
The Resolution
The Message
The Defences
The Record

Sedang merekrut, atau membangun hal serupa?

Saya terbuka untuk posisi full-time dan proyek freelance tertentu.