- Go 1.22 mengubah sumber bilangan acak bawaan di
math/randdanmath/rand/v2menjadi generator yang kuat secara kriptografis, sehingga sangat mengurangi dampak jika terjadi kesalahan penggunaan di tempat yang seharusnya memakaicrypto/rand - Generator Go 1 lama adalah linear feedback shift register yang menggunakan status 607 buah
uint64, sehingga dengan mengamati 607 output saja, nilai masa lalu dan masa depan bisa dipulihkan - PCG-DXSM di
math/rand/v2meningkatkan kualitas statistik bilangan acak dan ukuran status, tetapi tetap tidak menjamin ketaktertebakan yang dibutuhkan untuk nilai rahasia - ChaCha8Rand yang baru menggunakan seed 32 byte, melakukan re-keying setiap 16 blok, dan memakai status 300 byte per core, serta diterapkan pada
math/rand/v2, sebagianmath/rand, dan seed hash map - Biaya performanya terbatas: ChaCha8Rand memang lebih lambat daripada generator Go 1, tetapi tidak sampai 2x, dan pada server umum selisihnya tidak melebihi 3ns sehingga keuntungan keamanannya lebih besar bagi sebagian besar program
Default bilangan acak yang diubah Go 1.22
- Go 1.22 mengubah default di
math/randdanmath/rand/v2agar menggunakan generator pseudorandom yang kuat secara kriptografis - Tujuannya adalah mengurangi dampak ketika pengembang tanpa sengaja memakai
math/randdi tempat yang seharusnya membutuhkancrypto/rand - API bilangan acak di Go secara tradisional dibagi menjadi dua kategori
math/rand: bilangan acak statistik untuk simulasi, sampling, analisis numerik, algoritme acak non-kriptografis, fuzzing, shuffle, exponential backoff, dan sebagainyacrypto/rand: bilangan acak kriptografis untuk kebutuhan yang memerlukan ketaktertebakan seperti kunci dan token
Mengapa bilangan acak statistik tidak cukup
- Generator bilangan acak statistik bisa cukup untuk banyak penggunaan non-kriptografis jika lolos uji statistik dasar
- Namun, pengamat yang mengetahui algoritmenya sering kali dapat memprediksi urutan berikutnya setelah melihat cukup banyak output
sranddanranddi Unix V3 adalah bentuk awal yang kemudian memengaruhi API bilangan acak di C dan berbagai bahasa lain- Menetapkan status dari seed integer tunggal
- Menghitung nilai berikutnya dengan metode linear congruential generator (LCG)
- Karena status internalnya sederhana, hanya dengan satu output pun nilai masa depan bisa dihitung dengan mudah
- Pada LCG, konstanta dapat dipilih agar semua nilai output yang mungkin muncul satu kali sebelum berulang, tetapi bit-bit rendahnya memiliki kelemahan berupa pengulangan dengan periode pendek
Struktur dan kelemahan generator Go 1
- Generator
math/randdi Go 1 berasal dari keluarga linear feedback shift register - Status internalnya adalah slice
vecyang berisi 607 buahuint64vec[606]adalah “tap”vec[334]adalah “feed”- Untuk membuat nilai berikutnya, tap dan feed dijumlahkan menjadi
x, laluxdisimpan di posisi feed dan dikembalikan
- Implementasi nyatanya tidak menggeser seluruh slice, tetapi hanya memindahkan posisi tap dan feed ke belakang untuk mengurangi biaya
- Pembuatan nilai berikutnya memerlukan dua pengurangan, dua penjumlahan kondisional, dua load, satu penjumlahan, dan satu store
- Karena nilai yang dikembalikan adalah salah satu elemen vektor status internal, 607 output sudah cukup untuk membocorkan seluruh status
- Dengan mengisi
vecyang sama dan menjalankan algoritmenya, nilai masa depan bisa diprediksi - Dengan menjalankan algoritme secara terbalik, nilai masa lalu juga bisa dipulihkan
- Dengan mengisi
- Generator Go 1 memang bukan untuk tujuan keamanan, dan kualitas angka yang dihasilkannya juga bergantung pada cara
vecawal diinisialisasi
Perbaikan yang dibawa PCG dan batasannya yang tersisa
math/rand/v2mengadopsi PCG karya Melissa O’Neill sebagai generator bilangan acak statistik yang lebih modern- PCG di Go berbasis LCG 128-bit dan menggunakan fungsi
scrambleuntuk mereduksi status 128-bit menjadi output 64-bit - Dalam pembahasan proposal, Go menggunakan
scrambleberbasis perkalian berdasarkan usulan O’Neill- Bentuk ini disebut PCG-DXSM
- Numpy juga menggunakan bentuk PCG ini
- Status PCG jauh lebih kecil daripada generator Go 1
- Generator Go 1: 607 buah
uint64 - PCG: dua buah
uint64
- Generator Go 1: 607 buah
- PCG tidak terlalu sensitif terhadap nilai status awal dan lolos berbagai uji statistik, tetapi tetap tidak menjamin ketaktertebakan
- PCG-XSL-RR dapat dibalik
- PCG-DXSM juga tidak akan mengejutkan jika ternyata dapat dibalik
- Untuk pembuatan nilai rahasia, yang dibutuhkan adalah generator lain, bukan PCG
Bilangan acak kriptografis dan peran sistem operasi
- Bilangan acak kriptografis harus secara praktis tidak dapat diprediksi, bahkan oleh pengamat yang mengetahui cara pembuatannya dan telah melihat banyak output sebelumnya
- Protokol kriptografi, kunci rahasia, perdagangan modern, dan privasi online bergantung pada bilangan acak kriptografis
- Penyediaan bilangan acak sebenarnya ditangani oleh sistem operasi
- Sistem operasi mengumpulkan keacakan dari perangkat fisik seperti mouse, keyboard, disk, dan timing jaringan
- Belakangan ini juga dimanfaatkan noise listrik yang diukur langsung oleh CPU
- Setelah sistem operasi mengumpulkan keacakan yang cukup, misalnya minimal 256 bit, sistem akan membuat urutan bilangan acak panjang menggunakan algoritme hash atau kriptografi
- Dulu perangkat file seperti
/dev/randomumum digunakan, tetapi sistem operasi modern kini menyediakan syscall secara langsung crypto/randdi Go menyembunyikan perbedaan antar-OS dan menyediakan antarmuka yang sama lewatrand.Read
Desain ChaCha8Rand
- Generator baru ChaCha8Rand di Go 1.22 adalah bentuk yang sedikit dimodifikasi dari cipher stream ChaCha karya Daniel J. Bernstein
- ChaCha juga banyak digunakan dalam bentuk ChaCha20 pada TLS dan SSH
- Too Much Crypto karya Jean-Philippe Aumasson menilai bentuk 8-round, yaitu ChaCha8, juga aman, dan ChaCha8 kira-kira 2,5 kali lebih cepat
- ChaCha8Rand memakai ChaCha8 sebagai
rand.Source, sehingga blok yang dihasilkan tidak di-XOR dengan input, melainkan langsung digunakan sebagai stream bilangan acak- Ini setara dengan mengenkripsi atau mendekripsi data yang seluruhnya bernilai 0
Perubahan pada ChaCha8Rand
- ChaCha8Rand menggunakan seed 32 byte sebagai kunci ChaCha8
- ChaCha8 menghasilkan blok 64 byte, dan perhitungannya memperlakukan blok sebagai 16 buah
uint32 - Implementasi umum dapat menghitung 4 blok sekaligus dengan instruksi SIMD, tetapi untuk dipakai sebagai input XOR, blok yang terinterleaving perlu diurai lagi
- ChaCha8Rand mendefinisikan blok terinterleaving itu sendiri sebagai stream bilangan acak, sehingga menghilangkan biaya unshuffle
- Pada tahap akhir blok ChaCha8, nilai tertentu ditambahkan ke tiap
uint32- Setengahnya adalah material kunci dan setengahnya lagi adalah konstanta yang sudah diketahui
- ChaCha8Rand tidak menambahkan kembali konstanta yang diketahui itu, sehingga menghapus setengah dari penjumlahan akhir
- Setiap blok hasil ke-16, 32 byte terakhir digunakan sebagai kunci untuk 16 blok berikutnya
- Re-keying ini memberikan semacam forward security
- Sekalipun seluruh status memori generator bocor, yang bisa dipulihkan hanya nilai sejak re-keying terakhir, bukan nilai masa lalunya
- Go memublikasikan spesifikasi C2SP ChaCha8Rand dan test case agar implementasi lain dengan seed yang sama dapat berbagi repeatability yang sama dengan implementasi Go
Lokasi penerapan di standard library
- Runtime Go mempertahankan status ChaCha8Rand per core yang di-seed dengan bilangan acak kriptografis dari sistem operasi
- Ukuran status per core adalah 300 byte
- Pada sistem 16 core, ukurannya setara dengan status tunggal generator Go 1 bersama yang berukuran 4.872 byte
- Karena statusnya per core, bilangan acak bisa dihasilkan cepat tanpa lock contention
- Fungsi paket
math/rand/v2selalu menggunakan ChaCha8Rand- Contoh:
rand.N,rand.Float64
- Contoh:
- Fungsi paket
math/randmenggunakan ChaCha8Rand jikarand.Seedbelum dipanggil- Contoh:
rand.Intn,rand.Float64 - Jika
rand.Seeddipanggil, perilakunya harus kembali ke generator Go 1 demi kompatibilitas
- Contoh:
- Runtime memilih seed hash untuk map baru dengan ChaCha8Rand, menggantikan generator berbasis wyrand sebelumnya
- Jika penyerang mengetahui fungsi hash tertentu pada implementasi map, ia bisa menyiapkan input untuk memaksa map berjalan dalam waktu kuadratik
- Menggunakan seed per map, bukan satu seed global, juga menghindari bentuk degradasi lain
- Tidak sepenuhnya jelas apakah seed map benar-benar membutuhkan bilangan acak kriptografis, tetapi pergantian ini sederhana dan merupakan pilihan yang hati-hati
- Kode yang membutuhkan instance ChaCha8Rand terpisah dapat membuat
rand.ChaCha8secara langsung
Mengurangi dampak kesalahan keamanan
- Go bertujuan membantu penulisan kode yang aman secara default dengan mengurangi atau menghapus kesalahan umum yang menimbulkan masalah keamanan
- Ketika
Readpadamath/randdinyatakan deprecated di Go 1.20, ditemukan bahwa sebagian pengembang memakaimath/randdi tempat yang sebenarnya membutuhkancrypto/rand, seperti pembuatan material kunci - Di Go 1.20, kesalahan seperti ini merupakan masalah keamanan yang serius
- Harus diselidiki untuk apa kunci itu digunakan
- Bagaimana kunci itu mungkin terekspos
- Apakah output bilangan acak lain memberi petunjuk bagi penyerang untuk menurunkan kunci
- Di Go 1.22, kesalahan yang sama tetaplah kesalahan, tetapi kemungkinan berubah menjadi bencana keamanan menjadi lebih kecil
- Meski begitu, untuk nilai rahasia tetap lebih baik memakai
crypto/rand- Kernel sistem operasi dapat melindungi nilai acak dengan lebih baik
- Kernel terus menambahkan entropi baru ke generator
- Implementasi kernel telah menerima lebih banyak peninjauan
Kasus yang tampak tidak seperti kriptografi
- Pembuatan UUID acak bisa terlihat cukup memakai
math/randkarena UUID bukan nilai rahasia - Namun, jika
math/randdi-seed dengan waktu saat ini, komputer yang berbeda bisa menghasilkan nilai yang sama ketika berjalan pada saat yang sama- Kemungkinan ini lebih besar pada sistem yang hanya menyediakan presisi waktu milidetik
- Bahkan dengan auto-seeding berbasis entropi OS di Go 1.20, seed generator Go 1 tetap hanya integer 63-bit
- Program yang membuat UUID saat startup dibatasi pada 2⁶³ kemungkinan UUID pertama
- Setelah sekitar 2³¹ UUID, peluang tabrakan mulai muncul
- ChaCha8Rand di Go 1.22 di-seed dengan entropi 256 bit
- UUID pertama yang mungkin menjadi 2²⁵⁶
- Tidak perlu khawatir tentang tabrakan
- Load balancing di mana server frontend secara acak menugaskan permintaan ke server backend juga dapat memerlukan bilangan acak yang tidak dapat diprediksi
- Jika penyerang dapat mengamati penugasan dan mengetahui algoritme yang bisa diprediksi, ia dapat memusatkan permintaan mahal ke backend tertentu
- Pada generator Go 1, ini jarang tetapi mungkin terjadi
- Di Go 1.22, ini bukan masalah
Karakteristik performa
- Keunggulan keamanan ChaCha8Rand memang memiliki biaya kecil, tetapi performanya tetap berada pada kisaran yang sama dengan generator Go 1 dan PCG
- Ada dua operasi pembanding
Uint64: mengembalikanuint64berikutnya dari stream bilangan acakN(1000): mengembalikan bilangan acak dalam rentang[0, 1000)
- Pada chip x86 64-bit yang dibangun dengan
GOARCH=386lalu dijalankan dalam mode 32-bit, PCG lebih lambat daripada ChaCha8Rand karena perkalian 128-bit milik PCG- ChaCha8Rand menggunakan aritmetika SIMD 32-bit
- Pada sebagian sistem,
Go 1: Uint64lebih cepat daripadaPCG: Uint64, tetapiGo 1: N(1000)lebih lambat daripadaPCG: N(1000)N(1000)pada Go 1 memakai dua pembagian integer 64-bit untuk penyempitan rentangN(1000)pada PCG dan ChaCha8 sebagian besar menggunakan algoritmemath/rand/v2yang lebih cepat dan menghindari pembagian
- Secara keseluruhan, ChaCha8Rand lebih lambat daripada generator Go 1, tetapi tidak lebih dari 2x lebih lambat
- Pada server umum, selisihnya tidak melebihi 3ns, dan sangat sedikit program yang menjadikan selisih ini sebagai bottleneck
Kesimpulan
- Go 1.22 meningkatkan keamanan program tanpa perubahan kode
- Cara utamanya adalah memperkuat
math/randsendiri untuk mengurangi masalah umum ketikamath/randkeliru dipakai sebagai pengganticrypto/rand - Ada juga contoh seperti paket npm
keypairyang mencoba membuat pasangan kunci RSA dengan JavaScriptMath.randomsaat Web Crypto API tidak tersedia - Keamanan sistem tidak bisa bergantung pada asumsi bahwa pengembang tidak akan pernah melakukan kesalahan
- ChaCha8Rand di Go 1.22 menunjukkan bahwa pendekatan memakai generator pseudorandom yang kuat secara kriptografis bahkan untuk bilangan acak “matematis” pun dapat memberikan performa yang kompetitif dibanding generator lain
1 komentar
Komentar Hacker News
Seperti yang disebutkan di artikel, rclone melakukan kesalahan persis seperti ini.
Saat me-refactor kode yang menggunakan
Readdaricrypto/rand, import-nya otomatis berubah, dan mungkin karena bercampur dengan kode yang menggunakanmath/rand,goimportsmengubahnya menjadimath/rand.Akibatnya, yang dipakai bukan generator angka acak aman, melainkan generator deterministik yang di-seed oleh rclone dengan waktu, dan itu tidak terlihat di diff :-(
https://www.cvedetails.com/cve/CVE-2020-28924/
Jadi saya sangat mendukung perubahan ini.
goimportsdiubah agar memprioritaskancrypto/rand, saya tidak yakin apa yang terjadi saat refactoring itu.Mungkin di file yang sama ada kode yang menggunakan API khusus
math/rand.https://go-review.googlesource.com/24847
Bagaimanapun, senang melihat bagian seperti ini dirapikan.
math/randdigunakan. Sebenarnya tidak begitu; mereka hanya tertukar antara beberapa file, jadi bukan masalah besar, tetapi ini menunjukkan betapa membingungkannya keseluruhan hal ini.text/templatedanhtml/templatejuga mirip. Kalau dipikir lagi, penyamaran nama paket seperti ini adalah ide buruk."secure password generation golang", hampir semua contohnya menggunakanmath/rand.Lebih buruk lagi, semuanya menginisialisasi ulang seed dengan waktu saat ini tepat sebelum membuat kata sandi.
Saya mengetahuinya setelah menemukan seseorang memakai
math/randdi kode kami, lalu mencari tahu dari mana mereka menyalinnya.goimportshampir sejak awal menanganimath/rand.Readdancrypto/rand.Readsecara khusus.Namun, commit tahun 2016 di https://github.com/golang/tools/commit/0835c735343e0d8e375f0... menyebutkan ada masa ketika
"rand.Read"bisa ditafsirkan sebagai"math/rand".Mungkin kejadian itu terjadi pada periode tersebut.
"PredictableRand".Minggu lalu spacey juga memposting ini di https://news.ycombinator.com/item?id=40237491, tetapi tampaknya postingan itu keliru terkubur sebagai duplikat dari https://news.ycombinator.com/item?id=40224864.
Dua tulisan blog go.dev itu adalah dua bagian dari seri yang sama, tetapi cukup berbeda. Tulisan kali ini membahas algoritma generator angka acak aman yang efisien, sedangkan tulisan sebelumnya membahas desain API Go.
Russell Cox secara konsisten menghasilkan blog teknis, proposal, dan karya yang sangat bagus.
Jika ingin meningkatkan kejernihan menulis dan berpikir, Russell Cox adalah titik awal yang bagus.
Saat itu saya bahkan tidak tahu siapa Russ Cox, tetapi seri tulisannya benar-benar luar biasa.
Untuk materi gratis tentang implementasi regex, mungkin itu yang kualitasnya paling tinggi; berikutnya adalah beberapa buku yang berfokus pada compiler, tetapi itu tidak gratis dan juga tidak mudah dicari di web.
Saya pernah menggunakan
math/randdi tempat yang seharusnya wajib memakaicrypto/rand.Akibatnya, versi awal dnscrypt-proxy2 menggunakan kunci statis.
Penyebabnya adalah ekstensi VSCode yang otomatis menambahkan import. Di semua file sumber yang membutuhkan angka acak aman, saya secara hati-hati mengimpor
crypto/randlangsung, tetapi di satu file saya terlewat; semuanya tetap terkompilasi dan berjalan dengan baik, dan saya tidak menyadari bahwa ekstensi itu diam-diam menambahkan importmath/randke file tertentu tersebut.Sejak itu, untuk menghindari
randyang salah terimpor otomatis, saya mengimporcrypto/randdengan aliascryptorand.Sebagai catatan, Zig juga menggunakan generator angka acak berbasis ChaCha8, dan untuk operasi kriptografi pengguna tidak dapat menyediakan generator sendiri; generator yang aman selalu digunakan. Untuk pengujian, beberapa fungsi menerima seed eksplisit.
Untuk lingkungan terbatas, pustaka standarnya juga menyertakan generator yang lebih kecil berdasarkan permutasi Ascon dan konstruksi Reverie.
Pada 2016,
goimportsdiubah agar memprioritaskancrypto/randdibandingmath/rand(https://go-review.googlesource.com/24847), dan itu sebelum dukungan VSCode untuk Go muncul.Bahkan pada era 2020-an, saya sering bertanya-tanya mengapa implementasi random default di berbagai bahasa pemrograman masih memakai generator bilangan acak cepat seperti LFSR atau MT.
Tampaknya lebih baik mengambil sikap konservatif dengan menganggap orang tidak tahu apakah mereka membutuhkan generator bilangan acak semu atau generator bilangan acak semu yang aman secara kriptografis, lalu mengubah default ke yang kedua dan membiarkan hanya orang yang membutuhkan yang pertama memilihnya secara eksplisit.
Jika developer tidak secara eksplisit memilih mesin random yang akan digunakan, mereka akan mendapatkan generator yang aman secara kriptografis.
Bagian yang sulit sekarang adalah meyakinkan orang untuk pindah ke API baru. Lebih jauh lagi, bahkan memindahkan orang dari
mt_rand(), yang memakai instance globalMt19937, kerandom_int()berbasis CSPRNG yang sudah tersedia sejak PHP 7.0 pun tidak mudah.[1] https://www.php.net/releases/8.2/en.php#random_extension
Dalam use case saya, ada puluhan ribu komponen, dan setelah diprofiling, sebagian besar waktu inisialisasi struktur data ternyata dihabiskan di
Read()milikcrypto/rand, yang di MacBook saya menjalankan system call.Setelah library itu saya patch agar memakai
Read()darimath/rand, performanya meningkat besar.Selain
math/randmemang lebih cepat, saya juga khawatir akan menguras entropy pool sistem tanpa alasan khusus. Dalam kasus ini, satu-satunya alasan ID perlu bersifat acak adalah agar setelah struktur data diserialisasi/deserialisasi, komponen bisa ditambahkan lagi nanti, dan saya tidak berniat melakukan itu.Saya tidak tahu persis bagaimana timing perubahan yang dibahas di blog ini berkaitan dengan pengalaman saya. Mungkin saya memakai versi lama library tersebut, dan kalau sekarang
crypto/randpada dasarnya sudah hampir tak bisa dibedakan darimath/rand, ya bagus saja :-)Ukuran state-nya masih relatif besar (64 byte vs 16 byte), tetapi jauh lebih baik daripada
mt19937atau PRNG lama Go.Jika CSPRNG jauh lebih lambat, seperti umumnya terjadi pada CSPRNG biasa yang bukan varian ChaCha dengan round dikurangi, daya tariknya sebagai default akan berkurang.
Ada satu faktor kecil lain yang mendorong orang ke PRNG meski mereka tidak membutuhkan seed. API CSPRNG selalu menyertakan error yang harus ditangani untuk mengantisipasi kegagalan system call atau kekurangan entropi.
Seberapa sering pembacaan
crypto/randbenar-benar gagal? Seberapa banyak harus membaca untuk menguras entropi di sistem modern? Saya belum pernah melihat kegagalan bahkan pada miliaran request, danddjuga berjalan baik.Saya jadi bertanya-tanya apakah API bergaya
Must/panicmungkin lebih cocok sebagai default untuk sebagian besar use case.Sebagai tambahan, saya melihat paket
secretsdi Python (https://docs.python.org/3/library/secrets.html), dan tidak ada satu pun penyebutan bahwa ia bisa melempar exception. Apakah dalam praktiknya hal itu memang tidak terjadi?Dengan sedikit kehilangan performa, kita mendapat jaminan yang jauh lebih kuat bahwa bencana tidak terjadi karena memakai generator bilangan acak yang salah.
Sayang sekali di hampir semua bahasa, developer masih harus memperhatikan sudut tajam ini.
Sebagai tambahan bagi yang belum tahu,
gosecdan perluasannya,golangci-lint, akan memberi peringatan atas penggunaanmath/rand.https://github.com/securego/gosec/blob/d3b2359ae29fe344f4df5...
math/rand/v2adalah bisa memakainya di perusahaan tanpa directivenolintdan diskusi PR sesudahnya.Saya masih menafsirkan rekomendasi terkait keamanan dan opsi v2 baru ini.
Postingan blog memakai kalimat seperti “untuk nilai rahasia, Anda butuh yang lain”, lalu membahas secara detail randomness kriptografis, ChaCha8, dan cara ia di-seed dari random sistem, sehingga memberi kesan sangat “aman”.
Namun dokumentasi paketnya mengatakan begini:
... but it should not be used for security-sensitive work ... This package's outputs might be easily predictable regardless of how it's seeded. For random numbers suitable for security-sensitive work, see the crypto/rand package.Kalau begitu, mengapa postingan blog memberi kesan seolah
math/rand/v2dipakai untuk “nilai rahasia”?Singkatnya, apakah maksudnya semua hal yang sensitif tetap harus memakai
crypto/rand, dan peningkatan yang dijelaskan di sini hanyalah jaring pengaman ketika seseorang memakaimath/rand/v2secara tidak semestinya?math/rand/v2memang bukan yang optimal, tetapi jika seseorang secara keliru memakainya di tempat yang seharusnya memakaicrypto/rand, itu tidak lagi langsung menjadi cacat keamanan yang fatal.Di tulisannya juga disebutkan begini:
Tetap lebih baik memakai
crypto/rand. Kernel sistem operasi lebih mampu menjaga nilai random tetap rahasia dari berbagai serangan pengintaian, kernel terus menambahkan entropi baru ke generator, dan ia telah mendapat lebih banyak peninjauan. Namun, memakaimath/randsecara tidak sengaja tidak lagi menjadi bencana keamanan.Bahkan pada benchmark terburuk, strategi baru ini hanya sekitar setengah lebih lambat dibanding generator angka acak yang tidak aman, dan sebagian besar benchmark hasilnya jauh lebih dekat
Go berhasil menyeimbangkan keamanan dan performa dengan baik untuk pustaka standar dan aplikasi yang dibangun di atasnya. Semoga ekosistem lain juga mengikuti
Jika aplikasi membutuhkan angka acak yang cepat dan tidak aman, generator internal harus diimplementasikan sendiri
Menaruh angka acak yang tidak aman di tempat yang mudah dijangkau adalah alat untuk mencelakakan diri sendiri yang seharusnya bisa disingkirkan
Mendorong orang untuk berasumsi bahwa primitif
"random"aman secara kriptografis berarti mendorong praktik burukMenjadikan
math/rand/v2aman secara kriptografis mungkin menyelesaikan satu masalah, tetapi sekarang sesuatu yang tampaknya tidak menjanjikan keamanan menjadi “baik-baik saja”Secara umum, fungsi
math/randtidak memiliki konvensi bahwa ia aman secara kriptografis. Jika itu diubah sehingga kode buruk kebetulan berjalan dengan benar, hal itu bisa menutupi kesalahan lain apa yang mungkin kita buat jika kita melakukan kesalahan yang begitu jelas seperti inimath/randdi Go 1 lebih tepat disebut additive lagged Fibonacci generatorPublikasi pertamanya adalah makalah oleh Green, Smith, dan Klem
[1] https://doi.org/10.1145/320998.321006
Saya juga tahu https://www.leviathansecurity.com/blog/attacking-gos-lagged-..., dan di sana juga disebut lagged Fibonacci generator
Rob Pike dan saya beberapa bulan lalu berkorespondensi lewat email dengan Don Mitchell, yang menulis versi C asli dari generator Go 1, untuk menanyakan bagaimana ia menjelaskan algoritme ini, dan ia menjawab, “seingat saya, Jim dan saya mengimplementasikan generator mirip LFSR milik Marsaglia”
Saya rasa kedua deskripsi itu—lagged Fibonacci dan generator mirip LFSR—sama-sama benar dari sudut pandang yang berbeda. Keduanya boleh saja, tetapi di tulisan ini saya memilih memakai penjelasan dari penulis aslinya
Kalau harus menyebut satu kekurangan kecil, di sini tampaknya keacakan statistik dan generator angka acak semu tercampur penggunaannya
Definisi keacakan statistik di wiki adalah “sebuah deret angka dikatakan acak secara statistik ketika tidak memiliki pola atau keteraturan yang dapat dikenali”
Apakah definisi ini juga berlaku untuk true random number generator (TRNG)? Kita semestinya berharap demikian. Setidaknya dalam jangka panjang atau pada batasnya harus begitu. Jika tidak, itu bukan TRNG
TRNG harus menghasilkan “deret angka tanpa pola atau keteraturan yang dapat dikenali” dalam jangka panjang
Jadi, keacakan statistik tidak berarti PRNG, tetapi dapat dikatakan bahwa itu juga berlaku untuk TRNG
Masalahnya tampaknya muncul karena ada banyak uji keacakan statistik untuk memverifikasi apakah PRNG memiliki bentuk keacakan statistik yang terbatas
Jadi untuk mengidentifikasi PRNG, istilah “generator angka acak semu” mungkin lebih tepat daripada “keacakan statistik”. Meski begitu, ini hanya kekurangan yang sangat kecil