- Di Go 1.22, paket
math/rand yang sudah ada dan paket math/rand/v2 yang baru diperkenalkan diubah agar menggunakan generator bilangan acak yang aman secara kriptografis. Melalui perubahan ini, acak yang dihasilkan menjadi lebih baik, dan kerugian yang bisa timbul ketika pengembang keliru memakai math/rand alih-alih crypto/rand dapat sangat dikurangi.
Perbedaan antara keacakan statistik dan keacakan kriptografis
- Keacakan statistik cocok untuk simulasi, sampling, analisis numerik, algoritma acak non-kriptografi, pengujian acak, pengacakan input, random exponential backoff, dan sebagainya.
- Bahkan rumus matematika yang sangat dasar dan mudah dihitung pun dapat bekerja cukup baik untuk penggunaan seperti ini. Namun, pengamat yang mengetahui algoritma yang digunakan dapat memprediksi urutan berikutnya setelah melihat sejumlah nilai tertentu.
- Keacakan kriptografis pada praktiknya harus benar-benar tidak dapat diprediksi, meskipun seseorang telah mengamati nilai-nilai yang sebelumnya dihasilkan.
- Protokol kriptografi yang aman, kunci rahasia, perdagangan modern, privasi online, dan lain-lain sangat bergantung pada keacakan kriptografis.
Generator math/rand di Go 1
- Menggunakan metode Linear-feedback shift register(LFSR).
- Ada masalah karena state internal sepenuhnya terekspos sebagai vektor yang terdiri dari 607
uint64.
- Jika 607 nilai dibaca dari generator, seluruh state akan terekspos sehingga nilai berikutnya dapat diprediksi.
Generator PCG di math/rand/v2
- Menggunakan algoritma PCG karya Melissa O'Neill. Ini adalah 128-bit LCG yang diberi post-processing.
- Seluruh state hanya berupa satu angka 128-bit, dan pembaruannya dilakukan dengan perkalian serta penjumlahan 128-bit.
- Di Go, mengikuti usulan O'Neill, digunakan fungsi scramble berbasis perkalian alih-alih berbasis XOR agar bit tercampur lebih agresif.
- Perhitungannya lebih berat daripada generator Go 1, tetapi memori yang dibutuhkan untuk menyimpan state jauh lebih kecil, kurang sensitif terhadap nilai state awal, dan juga lolos uji statistik yang gagal dilalui generator lain.
- Namun, PCG tetap saja belum benar-benar tidak dapat diprediksi.
Keacakan kriptografis
- Pada akhirnya, sistem operasi harus mengumpulkan keacakan nyata dari noise perangkat fisik.
- Setelah keacakan yang cukup (256 bit atau lebih) terkumpul, ia dapat diperluas dengan hash kriptografis atau algoritma enkripsi untuk membuat deret bilangan acak sepanjang apa pun.
- Paket
crypto/rand di Go mengabstraksikan perbedaan antarmuka sistem operasi ini dan menyediakan antarmuka yang sama, yaitu rand.Read.
Generator ChaCha8Rand
- Generator baru yang dibuat dengan memodifikasi stream cipher ChaCha milik DJB.
- Menggunakan ChaCha8, yaitu versi 8 ronde. Ini 2,5 kali lebih cepat daripada ChaCha20 namun tetap aman.
- Seed 32 byte digunakan sebagai kunci ChaCha8. Setiap 16 blok, 32 byte terakhir dari blok yang dihasilkan dipakai sebagai kunci untuk 16 blok berikutnya sehingga memberikan forward secrecy.
rand.Float64, rand.N, dan lain-lain di math/rand/v2 selalu menggunakan generator ini.
math/rand juga menggunakan generator ini. Namun, jika rand.Seed dipanggil, generator Go 1 yang digunakan.
- Runtime juga menggunakan ChaCha8Rand saat memilih hash seed untuk map baru.
Mengatasi kesalahan keamanan
- Dengan memperkuat
math/rand, Go 1.22 membuat program lebih aman tanpa perlu perubahan kode.
- Misalnya, jika
Read dari math/rand salah dipakai untuk pembuatan kunci dan semacamnya, di Go 1.20 itu adalah masalah keamanan yang serius, tetapi di Go 1.22 itu hanya menjadi sebuah kekeliruan.
- Bahkan untuk penggunaan yang tidak tampak sebagai "kripto", seperti pembuatan UUID atau load balancing pada server frontend, memakai ChaCha8Rand membuatnya jauh lebih tangguh dibanding generator Go 1.
Kinerja
- ChaCha8Rand menunjukkan kinerja yang sebanding dengan generator Go 1 maupun PCG.
- Pada kode 32-bit, ChaCha8Rand lebih cepat daripada PCG yang memerlukan perkalian 128-bit.
- Berkat algoritma di
math/rand/v2 yang menghindari pembagian 64-bit, pada operasi N(1000) ChaCha8Rand atau PCG kadang lebih cepat daripada generator Go 1.
- Secara keseluruhan, ChaCha8Rand memang lebih lambat daripada generator Go 1, tetapi tidak pernah lebih lambat lebih dari dua kali lipat, dan pada server umum selisihnya tidak melebihi 3ns.
Opini GN⁺
- Penerapan ChaCha8Rand di Go 1.22 dapat disebut sebagai contoh perbaikan tingkat bahasa yang sangat baik: keamanan meningkat besar sementara penurunan kinerja tetap minimal. Sangat mengesankan bahwa kesalahan yang sering dilakukan pengembang diblokir sejak awal di tingkat bahasa.
- Seperti disebutkan di isi artikel, kesalahan semacam ini tidak terbatas pada Go dan juga sering ditemukan di bahasa lain. Keamanan sistem tidak semestinya ditentukan oleh kesalahan pengembang, sehingga bahasa lain juga perlu bergerak seperti Go: menggunakan generator pseudorandom yang kuat secara kriptografis bahkan untuk bilangan acak "matematis".
- Namun, ChaCha8Rand tidak cocok digunakan untuk primitive kriptografi seperti
crypto_box atau xchacha20poly1305. Untuk penggunaan seperti ini, crypto/rand tetap harus dipakai secara langsung.
- Bahwa runtime Go juga diubah untuk memakai ChaCha8Rand dalam pemilihan hash seed map terasa sedikit tak terduga. Tidak sepenuhnya jelas apakah hash seed benar-benar membutuhkan bilangan acak kriptografis, tetapi kesadaran keamanan tim pengembang yang ingin menutup kemungkinan serangan yang merepotkan sejak awal terlihat menonjol.
- Karena kualitas
math/rand, paket bawaan standar di tingkat bahasa, kini meningkat, ke depan tampaknya akan ada lebih banyak kasus aplikasi yang langsung memakai math/rand. Proyek yang selama ini menggunakan pustaka bilangan acak terpisah karena prediktabilitas math/rand kemungkinan akan merasakan manfaat dari perubahan ini.
1 komentar
Komentar Hacker News
Ringkasannya sebagai berikut:
Readpada paketmath/randdinyatakan deprecated, dan ditemukan kasus-kasus penggunaan yang keliru sebagai pengganticrypto/rand. Ini berujung pada kesalahan penggunaan generator bilangan acak deterministik yang rentan dari sisi keamanan.gosecataugolangci-lintmemberikan peringatan terhadap penggunaanmath/rand.math/rand/v2menggunakan sandi ChaCha8 dan di-seed dengan entropi sistem sehingga memberi kesan "aman", tetapi tetap tidak cocok untuk pekerjaan yang sensitif terhadap keamanan. Untuk itu harus menggunakancrypto/rand.math/randdi Go 1 secara tepat dapat dipandang sebagai additive lagged Fibonacci generator.math/randbaru, bahkan dalam kasus terburuk, hanya menunjukkan kecepatan sekitar setengah dari generator bilangan acak lama yang tidak aman, dan pada sebagian besar benchmark hampir tidak ada perbedaan. Go dinilai menjaga keseimbangan yang tepat antara keamanan dan performa di pustaka standarnya.java.util.Randomdi Java.