November 16, 2018

1728 words 9 mins read

Secure Remote Password

Secure Remote Password

Mengidentifikasi tanpa mengetahui

P ada bulan April tahun 2011 Sony Playstation Network, jaringan bermain bersama pengguna Playstation 3 dan Playstation Vita terkena kebocoran data karena retasan. Sebanyak 77 juta data pribadi pengguna dan 23 juta data pribadi Sony Online Entertainment bocor termasuk 23.400 data kartu kredit dan debit pengguna SOE Eropa dicuri menyebabkan PSN offline selama 2 minggu.

Kebocoran data terjadi lagi di Sony tahun 2014 dan data pribadi pegawai beserta keluarga mereka, aktor dan aktris serta ratusan dokumen berisi kata sandi bocor. Di tahun yang sama Yahoo teretas dan satu milyar data pribadi pengguna termasuk kata sandinya bocor. Tidak hanya itu, pada dasawarsa terakhir kebocoran data semakin mengkhawatirkan. Perusahaan seperti eBay, dan perusahaan rating kredit seperti Equifax dan bahkan Facebook. Kita juga tidak tahu berapa banyak retasan data di layanan daring yang ada di Indonesia.

Hash Saja Tidak Cukup

Hash adalah cara untuk mereduksi data menjadi sebuah bilangan dengan panjang yang tetap seperti 128-bit, 160-bit, 256-bit dan seterusnya. Melakukan hash terhadap kata sandi pengguna sebenarnya merupakan hal yang harus dilakukan semua penyedia layanan. Hanya saja, dengan hanya menggunakan hash tetap ada masalah berikut ini.

  1. Kebiasaan buruk pengguna menggunakan kata sandi lemah seperti abcde atau password123 dan juga penggunaan kata sandi yang sama untuk banyak layanan.
  2. Keamanan fungsi hash yang semakin berkurang mengikuti zaman. Algoritma seperti MD5 pernah berjaya pada zamannya, dan sekarang sudah tidak aman. Serangan seperti rainbow table, dan dictionary attack bisa digunakan untuk masuk menggunakan sistem yang menggunakan hash.
  3. Jika terkena kebocoran data, serangan bisa dilakukan secara luring terhadap data yang sudah banyak beredar di internet.

Secure Remote Password

Secure Remote Password (selanjutnya ditulis SRP) adalah sebuah protokol komunikasi yang memungkinkan penyedia layanan untuk mengautentikasi penggunanya dan membuktikan bahwa penggunanya mempunyai identitas yang benar tanpa menyimpan kata sandinya maupun data yang mempunyai hubungan langsung dengan kata sandi tersebut seperti hash. Penyedia layanan hanya menyimpan sebuah bilangan verifier untuk melakukan pembuktian. Metode seperti ini dikenal dengan nama zero knowledge password proof.

Dengan Secure Remote Password, penyadap informasi tidak pernah bisa melakukan serangan brute force terhadap data yang disadap tanpa melakukan komunikasi kepada kedua pihak yang bersangkutan. Selain, itu SRP __ juga tidak memerlukan pihak ketiga seperti yang dilakukan protokol lain semacam Kerberos.

Protokol SRP dibuat dengan memanfaatkan sifat dan metode dalam kriptografi seperti aritmetika modulus dan Diffie-Hellman sehingga memungkinkan untuk kedua pihak menghitung kunci rahasia secara independen untuk selanjutnya digunakan untuk saling memverifikasi satu sama lain dan selanjutnya bisa juga digunakan untuk melakukan enkripsi data.

Aritmetika Modulus

Sebelum kita masuk ke protokol SRP, saya akan kenalkan dengan aritmetika modulus. Secara informal, aritmetika modulus adalah operasi aritmetika yang dilakukan di dalam rentangan lingkaran bilangan bulat (ring of integer) 0 sampai dengan N-1 yang merupakan hasil modulus sembarang bilangan dengan N. Secara visual bisa digambarkan dengan jam dinding sebagai berikut.

image

Sebuah ring integer dengan N = 10

Untuk N=10 Untuk mendapatkan bilangan 7 bisa dari angka 7, 17, 57, 107, atau bahkan 10265746574657567. Jadi angka 7 susah diketahui asal mula bilangannya, dengan menggunakan angka N yang besar maka akan semakin susah untuk dicari bilangan awalnya. Sifat inilah yang dipakai dalam kriptografi. Beberapa sifat aritmetika modulus yang penting:

image

Sifat-sifat operasi modulus.

Pertukaran Kunci Diffie Hellman

Metode pertukaran kunci Diffie Hellman adalah suatu protokol di mana dua pihak dapat menghitung kunci rahasia yang sama tanpa saling mengirim kunci rahasia tersebut.

image

Pertukaran Diffie-Hellman digambarkan dengan warna

Dapat dilihat dari gambar di atas bahwa hasil akhir yang didapat Alice dan Bob adalah warna yang sama. Secara matematis langkah-langkahnya adalah sebagai berikut:

  1. Ambil sebuah bilangan prima p yang merupakan modulus dan g yang merupakan primitive root modulo dari p. Misalnya p = 23 dan g = 5. Kedua nilai ini tidak bersifat rahasia.
  2. Alice memilih satu bilangan sembarang a = 7 dan menghitung nilai A = g^a mod p = 5⁷mod 23 = 17. Bilangan a bersifat rahasia sementara A tidak.
  3. Bob memilih bilangan sembarang b = 10 dan menghitung nila B = g^b mod p. Sehingga B = 5¹⁰ mod 23 = 9. Bilangan b bersifat rahasia sedangakan B tidak.
  4. Alice dan Bob mengirim nilai A dan B sehingga kedua pihak punya nilai A dan B.
  5. Alice menghitung s = B^a mod _p = 9⁷_mod 23 = 4.
  6. Bob menghitung s = A^b mod p = 17¹⁰ mod 23 = 4
  7. Sekarang keduanya mempunyai angka 4 sebagai kunci rahasia bersama.

Penyebab Alice dan Bob mempunyai hasil akhir yang sama adalah karena sifat aritmetika modulus sebagai berikut:

image

Sifat aritmetika modulus yang dimanfaatkan diffie hellman.

Tentunya bilangan a, b dan p harus sangat besar dan jika p adalah bilangan prima dengan minimal 600 digit maka akan sangat mahal untuk menghitung a dan b hanya dengan mengetahui g, p dan g^a mod p.

Parameter-Parameter SRP

Protokol SRP mirip dengan Diffie-Hellman dengan menambahkan beberapa parameter. Semua operasi aritmetika selanjutnya akan kita jabarkan dalam ring integer N. Sehingga notasi gⁿ artinya gⁿ mod N. Parameter-parameter dalam protokol SRP adalah sebagai berikut

  1. N sebuah bilangan prima dimana N = 2q + 1 di mana q adalah Sophie-Germaine prime dan N adalah safe prime.
  2. H adalah sebuah fungsi hash seperti SHA-1, SHA-256, atau BLAKE2.
  3. Notasi H(a,b,c) adalah operasi H dengan gabungan nilai a, b, c. Cara menggabungkannya tidak dispesifikasikan tapi harus disetujui kedua pihak.
  4. g adalah generator untuk multiplicative group N.
  5. k adalah parameter yang digunakan oleh kedua pihak. Dalam SRP-6 k=3 sementara dalam SRP-6a k = H(g, N).

Bilangan-bilangana di atas adalah konstan dan bersifat publik. Untuk secara mudah mendapatkan bilangan tersebut. Kita bisa menggunakan perintah openssl sebagai berikut. openssl dhparam <opt> <bit>

Contohnya:

Membuat N dalam hex string:

image

Membuat hexstring untuk N

Membuat N dalam bentuk C-array:

image

Membuat N dalam bentuk C string yang siap di copy-paste ke program sebagai konstanta.

Secara default, nilai dari g adalah 2. Sementara nilai k bisa dihitung ketika program pertama kali berjalan.

Protokol SRP

Setelah parameter-parameter konstanta di atas sudah ditentukan kini saatnya kita menghitung nilai-nilai yang diturunkan dari identitas (nama pengguna dan kata sandi). Notasi | adalah notasi penggabungan string.

  • I adalah nama pengguna. Misalnya 'carol'.
  • p adalah kata sandi. Misalnya 'pass123'.
  • s adalah sembarang bilangan salt. Umumnya 16-byte (128-bit). Pastikan entropinya cukup sehingga tidak mudah digunakan untuk vektor serangan.
  • **x **adalah kunci privat yang dibuat dengan H(s, H(I | ‘:’ | p)). Jadi untuk I dan p di atas, nilai x = H(s, H( 'carol:pass123' )).
  • v** __ **adalah nilai verifier di mana v = g^x.

Anggaplah kita mempunyai aplikasi bernama Carol dan server bernama Steve. Maka nilai I, s, v adalah nilai yang dikirimkan dari Carol ke Steve untuk proses registrasi. Sementara nilai **x **lekas dihitung dan dibuang dari dalam memori.

image

Nilai yang dihitung dan didaftarkan Carol ke Steve

Proses autentikasi melibatkan beberapa nilai tambahan dengan notasi mirip dengan Diffie-Hellman hanya kita menambahkan faktor k dan v dan sebuah parameter pengacak u.

  1. Carol memilih suatu bilangan acak a yang bersifat privat. Dan menghitung A = g^a . A tidak boleh sama dengan N atau 0.
  2. Steve memilih suatu bilangan acak b yang bersifat privat. Dan mengambil s, dan v dari basis data lalu menghitung B = kv+g^b.
  3. Carol mengirim A ke Steve. Dan steve mengirim B ke Carol.
  4. Keduanya menghitung parameter pengacak u = H(A, B).
  5. Carol menghitung kunci S dengan rumus S = (B-kg^x)^(a+ux).
  6. Steve menghitung kunci S dengan rumus S = (Av^u)^b
  7. Steve dan Carol mempunyai nilai S yang sama.
  8. Steve dan Carol bisa menghitung kunci turunan S dengan hash biasa atau dengan HKDF.
  9. Carol mengirimkan M1= H(A|B|S) ke Steve, lalu Steve menghitung nilai yang sama jika nilai M1 Carol.
  10. Jika M1 Carol dan Steve sama, Steve lalu menghitung M2 = H(A|M1|S) lalu dikirim kan ke Carol. Jika tidak sama artinya autentikasi gagal.
  11. Jika perhitungan M1 dan M2 sama untuk Carol dan Steve artinya informasi pengguna dan kata sandinya cocok.

Secara visual dapat digambarkan sebagai berikut:

image

Protocol SRP

Jika ada pihak ketiga yang menyadap, maka yang akan disadap adalah nilai turunan dari A=g^a dan B=g^b, sehingga untuk mendapatkan nilai a dan b sangat mahal. Jika suatu saat data bocor dan v terpublikasi ke luar, proses untuk mendapatkan x dari g^x mod N sangat mahal. Itupun harus dilanjutkan dengan serangan lain untuk mendapatkan p. Jika H cukup aman, maka akan jadi sangat mahal untuk berusaha mendapatkan 1 kata sandi.

Catatan Implementasi

Dalam mengimplementasikan protokol SRP ini bisa menggunakan pustaka yang sudah ada. Tetapi ingat, karena fungsi H tidak ditentukan dalam protokol maka harus dilihat lebih jauh fungsi H apakah yang dipakai.

Bilangan seperti a dan b harus berupa big integer. Pastikan bahasa pemrograman yang dipakai harus mendukung struktur big integer, bahasa seperti Golang, Java, Dart dan Rust mempunyai pustaka untuk menangani bilangan big integer ini.

Sumber entropi untuk a dan b haruslah cryptographically random. Dalam Linux pastikan sumber entropinya adalah /dev/urandom.

Cek panjang dan entropi dari salt, dan A. Pastikan A tidak sama dengan 0 dan tidak sama dengan N.

Untuk mengirimkan bilangan A, B, M1 dan M2 bisa menggunakan pengkodean apapun bisa representasi binary nya dikirimkan langsung, dikirimkan nilai desimal atau hex nya. Atau bisa menggunakan base64. Jika ada yang masih bertanya-tanya soal binary encoding, saya pernah menuliskannya dalam Bahasa Inggris di sini.

Protokol ini cukup fleksibel karena selain fungsi H nya bisa diganti, untuk menghitung M1 dan M2 pun sebenarnya bisa menggunakan kunci turunan S daripada dengan S nya sendiri.

Implementasi Lengkap

Implementasi lengkap dari protokol ini sudah saya tulis di Github: https://github.com/ykode/srp_demo. Dengan beberapa catatan.

  • Penggabungan fungsi H(a, b) adalah dengan HMAC-SHA256.
  • M1 dan M2 dihitung dengan menggunakan kunci turunan dari S. Kunci turunan K dibuat dengan algoritma HKDF.
  • Diimplementasikan dalam bahasa Go (server), Dart (web/angular), dan Rust (command line).
  • Untuk server, Field dalam basis data untuk menyimpan verifier dan data-data big integer lainnya saya simpan dalam bentuk bytea dan bukan teks.

Konklusi

  • Dengan menggunakan SRP, penyedia layanan sama sekali tidak menyimpan identitas pengguna maupun data yang menggambarkan identitas pengguna seperti hash.
  • Proses autentikasi sama sekali tidak mengirimkan bilangan v dan hanya menggunakan bilangan-bilangan yang bersifat sementara. Bonusnya, selama autentikasi, kita mendapatkan shared secret yang bisa digunakan sebagai kunci untuk komunikasi selanjutnya atau bisa juga dipakai sebagai kunci sesi.
  • Dalam proses autentikasinya, perlu dua kali permintaan. Jadi untuk implementasinya cukup perlu usaha tambahan.
  • Jika terjadi kebocoran terhadap penyedia layanan maka menaikkan cost dalam usaha brute force oleh peretas.
  • Tidak mengatasi kebocoran disebabkan perangkat lunak yang terpasang di mesin pengguna untuk menyadap masukan seperti keylogger ataupun screen sharing/screen shot.

Saya sudah menulis rekaman beserta presentasi di video ini. Semoga berguna walaupun demonya masih kurang bagus.