Membedah e-KTP

Posting ini sekedar membahas tentang kartu tanda penduduk elektronik (e-KTP). Sampai saat ini saya belum pulang ke Indonesia untuk mengurus e-KTP karena KTP lama masih berlaku. Waktu orang tua saya datang ke sini tahun lalu saya sudah sempat ngoprek e-KTP mereka sedikit, dan sekarang selagi mereka berkunjung saya teruskan dan tuliskan hasil eksplorasi saya.

Sebagian isi tulisan ini didapat dari reverse engineering, dan sebagian lagi dari berbagai informasi yang tersebar di Internet. Ada juga bagian yang merupakan spekulasi saya dari informasi yang ada.

Security sebuah smart card

Sebuah smart card adalah sebuah komputer kecil, di dalamnya ada CPU, RAM, dan juga storage. Smart card diakses menggunakan reader, secara umum ada dua jenis: contact (menggunakan konektor fisik seperti SIM card) dan contactless (tanpa konektor fisik seperti kartu e-Money berbagai bank saat ini). Dari sisi programming keduanya sama saja. Kartu smart card yang baru umumnya juga sudah tahan (immune) terhadap side channel attack (DPA/SPA/FI dsb).

Hal yang membuat smart card penting untuk security adalah kemampuan smart card untuk melakukan komputasi (menghitung, melakukan hasing, enkripsi, dekripsi, dsb), dan sangat sulit untuk melakukan ekstraksi data dari smart card. Bayangkan seperti disuruh mengekstrak data di sebuah komputer yang dicor dan dimasukkan ke lemari besi.

Dari segi security, kita bisa memandang smart card ini seperti komputer remote yang melakukan komputasi yang tidak kita ketahui, dan kita tidak bisa mengekstrak informasi jika tidak ada bug pada implementasinya. Bayangkan sebuah sevice php seperti ini

<?php echo hash_hmac (“sha256”, $_GET[“q”], “[email protected]!ku” );?>

Jika kita tidak memiliki akses ke source code program tersebut, maka kita bisa mencoba-coba berbagai input, dan dengan melihat outputnya kita tidak akan bisa mengetahui bahwa kita memakai key “[email protected]!ku”.

Untuk berkomunikasi dengan smart card, kita mengirimkan perintah dalam bentuk byte-byte (dinamakan PDU atau protocol data unit), dan dibalas oleh card dengan status dan byte-byte hasil. Sebenarnya ini tidak berbeda jauh dari komunikasi lain seperti HTTP: kita mengirimkan request, dan card akan mengirimkan status dan balasan. Bahkan smart card generasi baru memang memasukkan server HTTP di dalamnya.

Riset smart card di level protokol (bukan level serangan fisik) bisa dilakukan dengan biaya relatif rendah. Card reader jenis contact dengan konektor USB bisa didapatkan dengan dengan harga kurang dari 10 USD, dan versi contactless (NFC) dengan konektor USB harganya sekitar 30 USD (atau jika punya Raspberry Pi atau Arduino, harga modul NFC-nya saja bisa kurang dari 5 USD).

Perhatikan bahwa: sebuah smart card bisa diisi program. Programnya bisa melakukan apa saja, baik itu memenuhi standar tertentu, atau melakukan sesuatu yang sifatnya custom. Sebagai informasi, kebanyakan  (tapi tidak semua) card sekarang ini diprogram menggunakan Java (teknologi JavaCard). Eksperimen Java Card bisa dilakukan di PC tanpa kartu menggunakan JCardSim.

Smart card juga memiliki protokol standar untuk filesystem. Kita bisa memilih Master File/Dedicated File (MF/DF) yang merupakan struktur direktori, dan EF (Elementary File) yang merupakan file. Semua “nama” pada file hanyalah bilangan yang umumnya dituliskan dalam notasi heksa desimal. Sebuah MF/DF/EF bisa diproteksi dan hanya bisa diakses dalam kondisi tertentu saja (dalam kondisi lain statusnya access denied)

SAM (Secure Access Module/Secure Application Module)

Jika komputer biasa digunakan untuk melakukan komputasi kriptopgrafi untuk dimasukkan ke e-KTP maka programnya akan rawan sekali diubah dan keynya gampang dicuri. Untuk mengatasi hal ini digunakan smart card lain yang dinamakan SAM. Ini hanya merupakan nama peran/role untuk smart card. Sebuah smart card biasa bisa menjadi SAM. Jadi sebuah SAM juga bisa diberi program apa saja. SAM ini bisa berupa chip yang ditanam di hardware, atau berupa kartu biasa. Biasanya SAM ini akan menggunakan jenis kartu contact.

Sekarang masalah security berpindah ke SAM. Tentunya SAM ini berbahaya jika jatuh ke tangan yang salah, jadi ada mekanisme keamanan yang diterapkan pada SAM e-KTP. Mekanismenya cukup sederhana, sehingga jika cukup niat bisa diakali. Ketika Kartu SAM diberikan untuk dipakai dengan aplikasi di sebuah komputer, file konfigurasi diberikan. File konfigurasi ini dienkrip dengan “Machine ID” (yang bisa dengan mudah didapatkan oleh program apapun).

Dengan menggunaakan file konfigurasi yang di XOR dengan machine ID, didapatkan key untuk mengakses Kartu SAM. Kartu tidak bisa dengan mudah dipakai di komputer lain tanpa mengakali program dan/atau mengganti machine ID. Jika N kali salah memasukkan machine ID, maka kartu SAM akan terblokir, dan harus meminta kartu SAM baru.

Keamanan ini hanya sekedar menghindari SAM yang “tercecer” di jalan agar tidak bisa sembarang dipakai. Jika ada yang berniat mengambil kartu SAM dan tahu dipakai di komputer mana (atau device mana), maka keamanan ini tidak membantu. Jadi bisa saja seoarang operator meminjam kartu SAM, dibawa pulang dan dipakai di rumah.

Data Pada e-KTP

Data yang disimpan pada e-KTP pada MF/DF 7F0A. Untuk memilih MF/DF ini bisa digunakan PDU

00A40000027F0A

Beberapa data yang ada di kartu:

  1. Data kontrol kartu (Card Control, pada EF: 6FF0), terbuka tapi spesifikasinya tidak diketahui
  2. Foto (EF: 6FF2), data ini terbuka
  3. Data Demografik/Biodata (6FF1), datanya diproteksi
  4. Data sidik jari: Minutiae1 (6FF4) dan Minutiae2 (6FF5), datanya diproteksi
  5. Scan tanda tangan (6FF3), datanya diproteksi
  6. ECDSA Signature (6FF6), datanya diproteksi

Mengekstrak Foto dari e-KTP

Foto dapat diekstrak dari e-KTP karena memang tidak diproteksi. Cara membacanya cukup mudah, pertama pilih MF/DF dan EF foto, lalu baca 2 byte pertama

00A40000027F0A
00A40000026FF2
00B0000002

Pada 2 byte pertama terdapat panjang (ukuran) data JPEG yang perlu dibaca.  Perhatikan bahwa apapun perintahnya akan selalu ada 2 byte status kembalian (9000 artinya adalah OK, bisa dibandingkan dengan HTTP Code 200):

=> 00 a4 00 00 02 7f 0a
<= 90 00 
Response : 
=> 00 a4 00 00 02 6f f2
<= 90 00 
Response : 
=> 00 b0 00 00 02
<= 06 fe 90 00
Response : 06 fe

Dalam kasus ini panjang file adalah 0x6fe byte = 1790 byte.

Berikutnya data bisa dibaca dengan mengirimkan PDU berikut ini berulang sampai selesai terbaca. Misalnya kita membaca dari offset 2 sebanyak 16 byte, berikutnya dari offset 18 sebanyak 16 byte, dst.

00BB<Offset High><Offset Low><Size>

Jika kita memiliki offset: 0x1234, maka Offset High adalah 0x12 dan Offset Low 0x34.  Teorinya kita bisa membaca sampai 255 byte sekali baca, kenyataannya card readernya bisa error. Di aplikasi e-KTP digunakan 112 byte sekali baca tapi di salah satu card reader saya, saya perlu memakai ukuran 16 byte sekali baca supaya reliable.

Data yang didapatkan adalah file JPEG biasa dengan ukuran 96×96 piksel.


Autentikasi Kartu

Untuk membaca data yang diproteksi, diperlukan key yang berada di SAM. Langkah pertama adalah mutual authentication untuk mendapatkan session key. Berdasarkan hasil reverse engineering,  protokol ini sepertinya berdasarkan Doc 9303 ICAO (Machine Readable Travel Documents) terutama Part 11 (Security Mechanisms for MRTDs).

Di dalam dokumen di atas, diasumsikan mesin pembaca memiliki key dalam memori komputer. Dalam dokumen itu protokolnya seperti ini (hanya garis besar, lihat contoh Appendix D di dokumen 9303 Part 11). Masing-masing pihak (kartu dan app desktop) memiliki SEED yang menjadi dasar untuk pembuatan key:

  • To Card: 0084000008 (request challenge/random number)
  • From Card: 8 byte random
  • From App: Generate random X1 (8 byte) dan X2 (16 byte), lalu  hoitung P1 = 3DES(X1 + RandomFrom Card +X2) , P2 = MAC(P1), hasilnya P1 + P2 ukurannya 40 byte, kirimkan ini ke kartu
  • From Card: kartu melakukan perhitungan serupa dan mengembalikan 40 byte
  • App melakukan komputasi dan menghasilkan session key.

Sedangkan protokolnya e-KTP seperti ini:

  • To SAM: Reset 00FF000000
  • From SAM: OK
  • To CARD: Get Challenge: 0084000008
  • From Card: challenge (8 byte)
  • To SAM: GenerateMutualAuth 00F10000 + CardControl + UID (8) + Challenge (8)
  • From SAM: 40 byte
  • To Card: ExternalAuth: 0082000028 + response from SAM
  • From Card: 40 byte
  • To SAM: VerifyMutualAuth: 00F2000028 + Response From Card

Perbedaannya adalah ada data Card Control dan UID kartu yang dikirim ke SAM. Sepertinya Card Control ini berisi informasi untuk pembuatan SEED, tapi tanpa source code ini tidak bisa diketahui detailnya.

Akan sangat panjang untuk membuktikan bahwa ini aman, tapi pada dasarnya: jika kita tidak punya key enkripsinya, meskipun kita bisa mengubah apapun di sisi app, maka kita tidak bisa mencari tahu key-nya.

Secure Messaging

Berdasarkan pada session key yang didapat pada proses autentikasi, maka setiap PDU yang dikirim akan dienkrip  dulu sebelum dikirim ke kartu dan yang diterima akan didekrip dulu sebelum diproses. Deskripsi ini cukup panjang, tapi ada gambar di dokumen yang menjelaskan ini.

Karena session key tidak pernah di simpan di PC, tapi di SAM, maka secara praktis yang terjadi adalah:

  1. Aplikasi membuat PDU unprotected (misalnya select EF)
  2. Aplikasi mengirimkan PDU unprotected ke SAM
  3. SAM membalas dengan PDU versi Secure Messaging
  4. Aplikasi mengirimkan PDU terenkripsi ke kartu e-KTP
  5. Kartu e-KTP membalas dalam PDU yang terenkrip
  6. Aplikasi mengirimkan PDU terenkrip dari e-KTP ke SAM
  7. SAM akan mendekrip PDU dan hasilnya dibaca oleh aplikasi di PC

Jadi dalam proses ini, meskipun kita mengetahui data terenkripsi dan hasil dekripsinya, kita tetap tidak tahu key yang digunakan (session ini selalu random dalam setiap koneksi).

Emulasi SAM dan e-KTP

Untuk membuat aplikasi e-KTP tanpa memiliki SAM. kita bisa menggunakan SAM dan e-KTP buatan kita sendiri dengan key yang kita masukkan sendiri tentunya ini tidak akan jalan di e-KTP “beneran” sampai kita memiliki akses untuk SAM yang benar. Hal ini sudah pernah diimplementasikan oleh BPPT dalam paper PERANCANGAN EMULATOR KTP ELEKTRONIK BERBASIS JAVA CARD UNTUK MENDUKUNG PENGUJIAN FUNGSIONALITAS PEMBACA KTP ELEKTRONIK INDUSTRI NASIONAL.

Dalam paper ini disebutkan bahwa metode key derivation yang digunakan e-KTP sifatnya rahasia dan mereka mengimplementasikan sendiri algoritma yang sekedar bisa dipakai oleh kartu SAM dan kartu KTP mereka sendiri.

Amankah e-KTP

Aman tergantung dari sudut pandang mana: dari pembuatan KTP, dan dari pemilik/pengguna KTP. Keamanan e-KTP ada pada SAM-nya.  Ini berarti beberapa hal:

  • Kartu SAM harus dijaga ketat, karena jika bisa dipinjam, maka bisa digunakan membuat KTP Aspal
  • Semoga key generation-nya aman. Saya sudah pernah menemukan kode SAM yang aman, tapi cara membuat key yang random hanya mengandalkan fungsi random biasa (bukan secure random) dan menggunakan seed waktu saat ini.
  • Semoga key utama disimpan dengan baik oleh kemendagri

Saat ini data foto sama sekali tidak diproteksi, sehingga seseorang bisa mengambil foto dari dompet yang tertutup. Menurut standar security MRTD, seharusnya data yang bisa dibaca dienkrip dengan informasi yang tertera di kartu. Misalnya untuk paspor, dari nomor paspor, tanggal lahir, tanggal kadaluarsa. Informasi ini tertera di kartu, jadi seseorang yang berusaha membaca dokumen tidak bisa membaca jika memang tidak memegang kartunya. Dengan ini kita bisa memastikan apakah benar isi data elektronik sama dengan data yang dicetak.

Sempat ada aplikasi POC reader e-KTP tapi sayangnya sudah dihapus dari Google Play (tapi masih bisa didownload dari sini). Aplikasi ini membaca data foto seperti saya jelaskan di atas. Sebenarnya agak berbahaya mempercayai data ini, karena mudah sekali membuat card yang jika dibaca dengan aplikasi tersebut akan keluar foto.

Semoga programmernya handal dan tidak membuat kesalahan implementasi. Saya agak khawatir membaca kode seperti ini di salah satu aplikasi yang saya dekompilasi.

Dari mana bisa tahu ini semua?

Pertama adalah mencari dulu aplikasi desktop e-ktp. Ini bisa dicari dengan query berikut di Google.

“index of” e-ktp inurl:.go.id/

Sekarang sepertinya sudah cukup sadar sehingga installernya lebih sulit dicari, tapi tahun lalu ini mudah sekali dicari. Programnya ditulis dalam .NET tanpa obfuscation sehingga mudah dibuka.

Berikutnya eksperimen diteruskan dengan e-KTP orang tua saya. Saya sudah mencoba beberapa attack yang umum, dan sepertinya semuanya aman.

Saat ini saya baru menemukan hal-hal kecil yang undocumented. Seperti halnya web server yang bisa dicari direktori tersembunyi dengan teknik “forced browsing”, kita bisa mengirimkan perintah berurutan ke smart card untuk mencari tahu perintah mana yang menghasilkan sesuatu tapi tidak terdokumentasi.

Demikian hasil oprekan e-KTP untuk saat ini. Mungkin di masa depan akan saya teruskan lagi. Saat ini belum ada ide serangan baru.

 

4 thoughts on “Membedah e-KTP”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.