Bagaimana cara menangani generator SecureRandom yang lambat?

165

Jika Anda ingin angka acak kriptografis kuat di Jawa, Anda gunakan SecureRandom. Sayangnya, SecureRandombisa sangat lambat. Jika digunakan /dev/randomdi Linux, ia dapat memblokir menunggu untuk membangun cukup entropi. Bagaimana Anda menghindari hukuman kinerja?

Adakah yang menggunakan Uncommon Maths sebagai solusi untuk masalah ini?

Adakah yang bisa mengkonfirmasi bahwa masalah kinerja ini telah diselesaikan di JDK 6?

David G
sumber
Tampaknya ini terkait dengan kelambatan SecureRandom.generateSeed () . Ada cacat yang ditolak yang menjelaskan kelambatan dan solusi: JDK-6521844: SecureRandom hang pada Sistem Linux
AlikElzin-kilaka
Lihat / dev / urandom (bukan / dev / random) .. Pertimbangkan hanya mendapatkan seed generator nomor acak dari urandom jika ada masalah pemblokiran.
jcalfee314
Terkait Windows: stackoverflow.com/questions/49322948/…
patrikbeno

Jawaban:

79

Jika Anda ingin data acak yang benar, maka sayangnya Anda harus menunggu untuk itu. Ini termasuk benih untuk SecureRandomPRNG. Matematika yang tidak umum tidak dapat mengumpulkan data acak yang sebenarnya lebih cepat dari itu SecureRandom, meskipun dapat terhubung ke internet untuk mengunduh data unggulan dari situs web tertentu. Dugaan saya adalah bahwa ini tidak mungkin lebih cepat daripada /dev/randomyang tersedia.

Jika Anda menginginkan PRNG, lakukan sesuatu seperti ini:

SecureRandom.getInstance("SHA1PRNG");

String apa yang didukung tergantung pada SecureRandompenyedia SPI, tetapi Anda dapat menghitungnya menggunakan Security.getProviders()dan Provider.getService().

Sun menyukai SHA1PRNG, jadi itu tersedia secara luas. Ini tidak terlalu cepat seperti PRNG berjalan, tetapi PRNG hanya akan menjadi angka-angka, tidak menghalangi untuk pengukuran fisik entropi.

Pengecualiannya adalah bahwa jika Anda tidak menelepon setSeed()sebelum mendapatkan data, maka PRNG akan melakukan seeded sendiri setelah pertama kali Anda menelepon next()atau nextBytes(). Biasanya akan melakukan ini menggunakan sejumlah kecil data acak benar dari sistem. Panggilan ini dapat memblokir, tetapi akan membuat sumber Anda nomor acak jauh lebih aman daripada varian "hash waktu saat ini bersama dengan PID, tambahkan 27, dan berharap yang terbaik". Namun, jika semua yang Anda butuhkan adalah angka acak untuk sebuah game, atau jika Anda ingin streaming diulangi di masa depan menggunakan seed yang sama untuk tujuan pengujian, seed yang tidak aman masih berguna.

Steve Jessop
sumber
Matematika yang tidak biasa hanya mengunduh data dari internet untuk disemai, itu tidak mengembalikan data acak ketika menghasilkan angka acak.
Dan Dyer
Sama dengan SecureRandom - / dev / urandom hanya untuk penyemaian.
AviD
Ya. Ketika si penanya mengatakan "jika Anda ingin nomor acak Anda menggunakan SecureRandom - ini bisa lambat", saya pikir mungkin ia menggunakan getSeed untuk semuanya dan menguras kumpulan entropinya. Cara mengatasinya bukan untuk mendapatkan JDK 6, itu menggunakan SecureRandom seperti yang dimaksudkan ;-)
Steve Jessop
@Dan Dyer - Saya mengoreksi komentar saya tentang Uncommon Maths. Saya memang melihat halaman Anda, jadi saya tahu bahwa dengan "angka acak" yang saya maksudkan "untuk seed-nya" daripada "kembali ke pengguna". Tapi Anda benar bukan itu yang saya katakan ...
Steve Jessop
"ini tersedia secara luas". Bukankah ini sudah termasuk dalam setiap JDK yang patuh? Itu ada dalam daftar nama standar keamanan java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Sean Reilly
176

Anda harus dapat memilih / dev / urandom Linux yang lebih cepat tapi sedikit kurang aman menggunakan:

-Djava.security.egd=file:/dev/urandom

Namun, ini tidak berfungsi dengan Java 5 dan yang lebih baru ( Java Bug 6202721 ). Solusi yang disarankan adalah menggunakan:

-Djava.security.egd=file:/dev/./urandom

(perhatikan tambahan /./)

Thomas Leonard
sumber
24
Perhatikan bahwa laporan Java Bug mengatakan "Bukan cacat". Dengan kata lain meskipun defaultnya adalah /dev/urandom, Sun memperlakukan ini sebagai string ajaib dan menggunakan /dev/randompula, jadi Anda harus memalsukannya. Kapan file:URL bukan file:URL? Setiap kali Sun memutuskan itu bukan :-(
Jim Garrison
6
Setelah menghabiskan banyak waktu untuk menyelidiki hal ini, tampaknya pengaturan normal, bahkan dengan file:/dev/urandomset in -Djava.security.egdatau di securerandom.sourcefile java.security, /dev/random/masih dibaca kapan saja SecureRandom.getSeed()(atau setSeed()dipanggil). Penanganannya dengan file:/dev/./urandomhasil dalam tidak membaca /dev/randomsama sekali (dikonfirmasi dengan strace)
matt b
7
/dev/urandomtidak kalah aman daripada /dev/randomketika diimplementasikan dengan CSPRNG modern: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo
Saya pikir ketakutan utama /dev/urandom/adalah apa yang terjadi jika Anda menggunakannya untuk menghasilkan rahasia pada perangkat keras baru di luar kotak, yang mungkin dalam keadaan yang cukup dapat diprediksi. /dev/urandom/tidak akan memblokir untuk entropi meskipun itu adalah satu kasus di mana Anda harus. Situasinya bahkan lebih buruk jika rahasianya persisten, seperti jika hal pertama yang dilakukan perangkat Anda saat boot pertama adalah menghasilkan pasangan kunci publik-swasta. Di luar dari situasi yang menakutkan itu, suatu kebaikan /dev/urandomlebih baik daripada menggunakan SecureRandomalgoritma umum pula.
Steve Jessop
1
Yang mana yang benar ? -Djava.security.egd = file: / dev /./ urandom atau file: /// dev / urandom @mattb
Aarish Ramesh
35

Di Linux, implementasi default untuk SecureRandomadalah NativePRNG(kode sumber di sini ), yang cenderung sangat lambat. Di Windows, defaultnya adalah SHA1PRNG, yang seperti yang ditunjukkan orang lain dapat Anda gunakan di Linux jika Anda menentukannya secara eksplisit.

NativePRNGberbeda dari SHA1PRNGdan AESCounterRNG Matematika yang Tidak Biasa dalam hal ia terus menerima entropi dari sistem operasi (dengan membaca dari /dev/urandom). PRNG lain tidak memperoleh entropi tambahan setelah penyemaian.

AESCounterRNG sekitar 10x lebih cepat daripada SHA1PRNG, yang IIRC itu sendiri dua atau tiga kali lebih cepat daripada NativePRNG.

Jika Anda memerlukan PRNG yang lebih cepat yang memperoleh entropi setelah inisialisasi, lihat apakah Anda dapat menemukan implementasi Java dari Fortuna . PRNG inti dari implementasi Fortuna identik dengan yang digunakan oleh AESCounterRNG, tetapi ada juga sistem pengelompokan entropi yang canggih dan penanaman ulang otomatis.

Dan Dyer
sumber
Tautan ini tidak berfungsi. uncommons-maths.dev.java.net/nonav/api/org/uncommons/maths/… . Apakah ada tempat saya bisa melihat ini?
UVM
@Unni Baru saja memperbarui tautan. Harap perhatikan bahwa klaim kinerja yang saya buat dalam jawaban ini mungkin tidak valid lagi. Saya pikir hal-hal mungkin menjadi lebih baik di versi Java terbaru dan mungkin ada perbedaan kinerja antara platform (yaitu Windows vs Liux).
Dan Dyer
Saya baru saja menjalankan satu contoh SecureRandom dengan MessageDigest dan membuat hexencoded itu. Seluruh operasi di windows 7 PC saya mengambil 33 milidetik. Apakah ini masalah. Saya menggunakan SHA1PRNG. SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); String randomNum = Integer baru (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); result = sha.digest (randomNum.getBytes ()); str = hexEncode (hasil);
UVM
24

Banyak distro Linux (kebanyakan berbasis Debian) mengkonfigurasi OpenJDK untuk digunakan /dev/randomuntuk entropi.

/dev/random menurut definisi lambat (dan bahkan dapat memblokir).

Dari sini Anda memiliki dua opsi tentang cara membuka blokir itu:

  1. Tingkatkan entropi, atau
  2. Mengurangi persyaratan keacakan.

Opsi 1, Tingkatkan entropi

Untuk mendapatkan lebih banyak entropi /dev/random, cobalah daemon yang telah dirajut . Ini adalah daemon yang secara terus-menerus mengumpulkan entropi HAVEGE, dan berfungsi juga dalam lingkungan tervirtualisasi karena tidak memerlukan perangkat keras khusus, hanya CPU itu sendiri dan sebuah jam.

Di Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

Di RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Opsi 2. Mengurangi persyaratan keacakan

Jika karena alasan tertentu solusi di atas tidak membantu atau Anda tidak peduli dengan keacakan yang kuat secara kriptografis, Anda dapat beralih ke sana /dev/urandom, yang dijamin tidak akan diblokir.

Untuk melakukannya secara global, edit file jre/lib/security/java.securitydi instalasi Java default Anda untuk menggunakan /dev/urandom(karena bug lain perlu ditentukan sebagai /dev/./urandom).

Seperti ini:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Maka Anda tidak perlu menentukannya di baris perintah.


Catatan: Jika Anda melakukan kriptografi, Anda perlu entropi yang baik. Contoh kasus - masalah PRNG android mengurangi keamanan dompet Bitcoin.

rustyx
sumber
Diperbaharui jawaban Anda, tetapi " /dev/randommenurut definisi lambat (dan bahkan dapat memblokir)" salah; sepenuhnya tergantung pada konfigurasi sistem. Mesin yang lebih baru mungkin memiliki misalnya RNG cepat dalam CPU yang dapat digunakan, dan mesin BSD umumnya memiliki implementasi yang sama untuk /dev/randomdan /devl/urandom. Namun, Anda mungkin tidak harus bergantung pada /dev/random kecepatan, tentu saja. Pada VM, Anda mungkin ingin menginstal toolset klien pada VM klien sehingga dapat menggunakan RNG dari OS host.
Maarten Bodewes
17

Saya memiliki masalah yang sama dengan panggilan untuk SecureRandommemblokir sekitar 25 detik pada server Debian tanpa kepala. Saya menginstal havegeddaemon untuk memastikan /dev/randomdisimpan di atas, pada server tanpa kepala Anda perlu sesuatu seperti ini untuk menghasilkan entropi yang diperlukan. Panggilan saya untuk SecureRandomsekarang mungkin membutuhkan milidetik.

guntur
sumber
4
apt-get install hasged kemudian perbarui-rc.d hasgeds default
Rod Lima
11

Jika Anda ingin keacakan yang benar-benar "kuat secara kriptografis", maka Anda memerlukan sumber entropi yang kuat. /dev/randomlambat karena harus menunggu acara sistem untuk mengumpulkan entropi (disk membaca, paket jaringan, gerakan mouse, penekanan tombol, dll.).

Solusi yang lebih cepat adalah generator nomor acak perangkat keras. Anda mungkin sudah memiliki satu bawaan untuk motherboard Anda; lihat dokumentasi hw_random untuk mengetahui cara mencari tahu jika Anda memilikinya, dan cara menggunakannya. Paket rng-tools termasuk daemon yang akan memasukkan perangkat keras yang dihasilkan ke dalam entropi /dev/random.

Jika HRNG tidak tersedia di sistem Anda, dan Anda bersedia mengorbankan kekuatan entropi untuk kinerja, Anda akan ingin menyemai PRNG yang baik dengan data dari /dev/random, dan biarkan PRNG melakukan sebagian besar pekerjaan. Ada beberapa PRNG yang disetujui NIST yang terdaftar di SP800-90 yang mudah untuk diimplementasikan.

Chris Kite
sumber
Poin bagus, tetapi kode saya adalah bagian dari aplikasi komersial. Saya tidak memiliki kendali atas lingkungan server. Saya pikir server target selalu tanpa mouse dan keyboard dan sepenuhnya bergantung pada disk dan I / O jaringan untuk entropi, yang mungkin merupakan masalah root.
David G
3
Saya menemukan bahwa / dev / random bergantung pada peristiwa sistem, jadi sebagai solusi sementara, saya hanya menggerakkan mouse saya bolak-balik sementara tes saya berjalan ....
David K
Hub 82802 untuk chipset i820 itu sangat lambat (RIP). Saya kagum Anda bisa mengumpulkan apa pun yang berguna darinya. Saya pikir saya menghabiskan lebih banyak waktu untuk memblokirnya daripada mengumpulkan oktet.
jww
6

Menggunakan Java 8, saya menemukan bahwa pada panggilan Linux SecureRandom.getInstanceStrong()akan memberi saya NativePRNGBlockingalgoritma. Ini sering memblokir selama beberapa detik untuk menghasilkan beberapa byte garam.

Saya beralih ke meminta secara eksplisit sebagai NativePRNGNonBlockinggantinya, dan seperti yang diharapkan dari namanya, itu tidak lagi diblokir. Saya tidak tahu apa implikasi keamanan dari ini. Mungkin versi non-pemblokiran tidak dapat menjamin jumlah entropi yang digunakan.

Pembaruan : Oke, saya menemukan penjelasan yang sangat bagus .

Singkatnya, untuk menghindari pemblokiran, gunakan new SecureRandom(). Ini menggunakan /dev/urandom, yang tidak memblokir dan pada dasarnya seaman /dev/random. Dari pos: "Satu-satunya saat Anda ingin memanggil / dev / random adalah ketika mesin pertama kali boot, dan entropi belum terakumulasi".

SecureRandom.getInstanceStrong() memberi Anda RNG terkuat mutlak, tetapi itu hanya aman untuk digunakan dalam situasi di mana sekelompok pemblokiran tidak akan mempengaruhi Anda.

Lachlan
sumber
1
Saya hanya mengizinkan getInstanceStrong() kunci jangka panjang, seperti untuk sertifikat TLS. Dan bahkan kemudian saya lebih suka menggunakan new SecureRandom()atau generator pasangan kunci yang sesuai FIPS atau generator nomor acak. Jadi ya, ini memberikan jawaban, jika /dev/urandom tidak memblokir: pada akhirnya tetap bergantung pada entropi sistem; tapi itu saran yang sangat bagus secara umum . Jika /dev/urandomblok, Anda mungkin harus memperbaiki sumber masalah daripada aplikasi Java Anda.
Maarten Bodewes
5

Ada alat (setidaknya di Ubuntu) yang akan memberi makan keacakan buatan ke dalam sistem Anda. Perintahnya sederhana:

rngd -r /dev/urandom

dan Anda mungkin perlu sudo di depan. Jika Anda tidak memiliki paket rng-tools, Anda harus menginstalnya. Saya mencoba ini, dan itu pasti membantu saya!

Sumber: matt vs dunia

David K.
sumber
2
Ini agak berbahaya karena sepenuhnya menonaktifkan estimasi level entropi kernel Linux, di seluruh sistem. Saya pikir untuk tujuan pengujian (baca: Jenkins menjalankan testuite aplikasi) menggunakan /dev/./urandom baik-baik saja, tetapi dalam produksi, tidak.
mirabilos
Ini sebenarnya satu-satunya solusi yang bekerja untuk saya. Saya punya masalah "tidak cukup entropi" ketika membangun proyek Android dengan Gradle di Jenkins CI, dan memberikan parameter ke build tidak membantu.
Slav
Saya harus menggabungkan sudo rngd -r /dev/urandomdengan sudo apt install rng-toolsdalam xenial
MrMesees
5

Saya menghadapi masalah yang sama . Setelah beberapa Googling dengan istilah pencarian yang tepat, saya menemukan artikel bagus ini di DigitalOcean .

telah menjadi solusi potensial tanpa mengorbankan keamanan.

Saya hanya mengutip bagian yang relevan dari artikel di sini.

Berdasarkan prinsip HAVEGE, dan sebelumnya berdasarkan pustaka yang terkait, telah memungkinkan menghasilkan keacakan berdasarkan variasi waktu eksekusi kode pada prosesor. Karena hampir tidak mungkin bagi satu keping kode untuk mengambil waktu yang tepat untuk dieksekusi, bahkan dalam lingkungan yang sama pada perangkat keras yang sama, waktu menjalankan satu atau beberapa program harus cocok untuk menebar sumber acak. Implementasi yang dirajam menambakan sumber acak sistem Anda (biasanya / dev / acak) menggunakan perbedaan penghitung cap waktu (TSC) prosesor Anda setelah menjalankan loop berulang kali

Cara memasang telah

Ikuti langkah-langkah di artikel ini. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Saya telah mempostingnya di sini

jadi-acak-bung
sumber
5

Masalah yang Anda rujuk /dev/randombukan dengan SecureRandomalgoritma, tetapi dengan sumber keacakan yang digunakannya. Keduanya orthogonal. Anda harus mencari tahu yang mana dari keduanya yang memperlambat Anda.

Halaman Matematika yang tidak biasa yang Anda tautkan secara eksplisit menyebutkan bahwa mereka tidak membahas sumber keacakan.

Anda dapat mencoba berbagai penyedia JCE, seperti BouncyCastle, untuk melihat apakah implementasinya SecureRandomlebih cepat.

Pencarian singkat juga mengungkapkan tambalan Linux yang menggantikan implementasi default dengan Fortuna. Saya tidak tahu banyak tentang ini, tetapi Anda dipersilakan untuk menyelidikinya.

Saya juga harus menyebutkan bahwa meskipun sangat berbahaya untuk menggunakan SecureRandomalgoritma yang diimplementasikan dengan buruk dan / atau sumber keacakan, Anda dapat melempar Penyedia JCE Anda sendiri dengan implementasi kustom SecureRandomSpi. Anda harus melalui proses dengan Sun untuk mendapatkan penyedia Anda ditandatangani, tetapi sebenarnya cukup mudah; mereka hanya perlu Anda mengirimi mereka faks formulir yang menyatakan bahwa Anda mengetahui pembatasan ekspor AS pada pustaka kripto.

ykaganovich
sumber
Penyedia JCE yang berbeda hanya digunakan jika mereka menggunakan sumber entropi lain yang pada dasarnya berarti mereka harus menggunakan perangkat keras tertentu, seperti HSM. Kalau tidak, mereka hanya akan mengalami perlambatan, tergantung pada seberapa banyak entropi yang mereka ekstrak dari sistem.
Maarten Bodewes
3

Gunakan acak aman sebagai sumber inisialisasi untuk algoritma berulang; Anda dapat menggunakan twister Mersenne untuk pekerjaan massal, bukan yang di UncommonMath, yang telah ada selama beberapa waktu dan terbukti lebih baik daripada prng lainnya.

http://en.wikipedia.org/wiki/Mersenne_twister

Pastikan untuk menyegarkan sekarang dan kemudian acak aman yang digunakan untuk inisialisasi, misalnya Anda dapat memiliki satu acak dihasilkan aman per klien, menggunakan satu generator acak semu mersenne twister per klien, memperoleh tingkat pengacakan yang cukup tinggi

Lorenzo Boccaccia
sumber
2
Jawaban ini salah: twister Mersenne bukan penghasil angka acak yang aman. Ini akan menjadi algoritma yang baik untuk Random, tetapi tidak untuk SecureRandom.
Maarten Bodewes
3

Menurut dokumentasi , berbagai algoritme yang digunakan oleh SecureRandom adalah, sesuai urutan preferensi:

  • Pada kebanyakan * sistem NIX
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBlocking
    4. NativePRNGNonBlocking
  • Pada sistem Windows
    1. SHA1PRNG
    2. Windows-PRNG

Karena Anda bertanya tentang Linux, saya mengabaikan implementasi Windows, dan juga SunPKCS11 yang hanya benar-benar tersedia di Solaris, kecuali Anda menginstalnya sendiri - dan Anda tidak akan menanyakan hal ini.

Menurut dokumentasi yang sama, apa yang digunakan algoritma ini

SHA1PRNG
Penyemaian awal saat ini dilakukan melalui kombinasi atribut sistem dan perangkat pengumpulan entropi java.security.

NativePRNG
nextBytes() menggunakan /dev/urandom
generateSeed()kegunaan/dev/random

NativePRNGB mengunci
nextBytes() dan generateSeed()menggunakan/dev/random

NativePRNGNonBlocking
nextBytes() dan generateSeed()gunakan/dev/urandom

Itu berarti jika Anda menggunakan SecureRandom random = new SecureRandom(), itu turun daftar itu sampai menemukan yang berfungsi, yang biasanya NativePRNG. Dan itu berarti bahwa itu berasal dari /dev/random(atau menggunakannya jika Anda secara eksplisit menghasilkan benih), lalu gunakan/dev/urandom untuk mendapatkan byte, int, dobel, boolean berikutnya, apa-yang-Anda-miliki.

Sejak /dev/random memblokir (itu memblokir sampai memiliki cukup entropi di kumpulan entropi), yang dapat menghambat kinerja.

Salah satu solusi untuk itu adalah menggunakan sesuatu seperti ditempa untuk menghasilkan entropi yang cukup, solusi lain menggunakan /dev/urandomsebagai gantinya. Meskipun Anda bisa mengaturnya untuk seluruh jvm, solusi yang lebih baik adalah melakukannya untuk instance khusus ini SecureRandom, dengan menggunakan SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking"). Perhatikan bahwa metode itu dapat melempar NoSuchAlgorithmException jika NativePRNGNonBlocking, jadi bersiaplah untuk mundur ke default.

SecureRandom random;
try {
    random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
    random = new SecureRandom();
}

Perhatikan juga bahwa pada sistem * nix lain, /dev/urandommungkin berperilaku berbeda .


Apakah /dev/urandomcukup acak?

Kebijaksanaan konvensional mengatakan bahwa hanya /dev/randomcukup acak. Namun, beberapa suara berbeda. Dalam "Cara yang Tepat untuk Menggunakan SecureRandom" dan "Mitos tentang / dev / urandom" , dikatakan bahwa /dev/urandom/itu sama baiknya.

Para pengguna di tumpukan Keamanan Informasi setuju dengan itu . Pada dasarnya, jika Anda harus bertanya, /dev/urandomboleh saja untuk tujuan Anda.

SQB
sumber
2

Saya sendiri belum menemukan masalah ini, tetapi saya akan menelurkan utas di awal program yang segera mencoba untuk menghasilkan benih, kemudian mati. Metode yang Anda panggil untuk tebusan akan bergabung ke utas itu jika masih hidup sehingga panggilan pertama hanya memblokir jika itu terjadi sangat awal dalam pelaksanaan program.

Nick
sumber
Ini adalah hack yang agak ekstrem, tetapi mungkin berhasil; tidak dikatakan bahwa PRNG yang digunakan tidak boleh menggunakan bahan benih tambahan yang masih bisa menyebabkan pemblokiran. Lebih disukai menggunakan nomor acak berbeda yang menyediakan atau memperbaiki entropi dalam sistem. Karena setidaknya dapat memberikan solusi sementara, saya memilih jawabannya.
Maarten Bodewes
2

Pengalaman saya hanya dengan inisialisasi lambat dari PRNG, bukan dengan generasi data acak setelah itu. Coba strategi inisialisasi yang lebih bersemangat. Karena mahal untuk dibuat, perlakukan seperti singleton dan gunakan kembali contoh yang sama. Jika ada terlalu banyak pertikaian utas untuk satu contoh, kumpulkan atau buat mereka utas-lokal.

Jangan kompromi pada pembuatan angka acak. Kelemahan di sana membahayakan keamanan Anda.

Saya tidak melihat banyak generator berbasis peluruhan atom COTS, tetapi ada beberapa rencana di luar sana untuk mereka, jika Anda benar-benar membutuhkan banyak data acak. Salah satu situs yang selalu memiliki hal-hal menarik untuk dilihat, termasuk HotBits, adalah John Walker's Fourmilab.

erickson
sumber
1
Saya selalu bertanya-tanya tentang hal ini, karena produk peluruhan hadronic hampir mencapai ideal dari sumber acak saya tidak bisa menyingkirkan keinginan saya untuk menggunakan itu daripada alat algoritmik. Untuk tujuan op, saya memutuskan sejak lama bahwa beberapa waktu front-end adalah endemik untuk semua alat yang aman. Jika seseorang akan membutuhkan pengacak, yang dapat dipanggil dalam konstruktor dan hanya ingat untuk membangun satu pada waktu buka halaman, itu terkubur di bawah avl swap-in dan bahkan pilih-pilih seperti saya itu tidak diperhatikan.
Nicholas Jordan
Chipset Intel 8xx (dan mungkin banyak lainnya) memiliki perangkat keras RNG yang menggunakan noise termal, efek kuantum yang benar-benar tidak dapat diprediksi. Modul Platform Tepercaya juga dapat memuat RNG perangkat keras, tetapi sayangnya, yang ada di laptop saya tidak.
erickson
Itu tergantung pada RNG spesifik jika benih satu kali atau jika ditanam kembali setelah beberapa saat. NIST menentukan PRNG yang melakukan reseed, tetapi banyak implementasi perangkat lunak tidak. Merestrukturisasi kode di sekitar singleton adalah ide yang mengerikan, terutama pada implementasi multithreaded; lebih baik memperbaiki sumber masalahnya: penyemaian lambat karena kurang entropi. Jika Anda menggunakan singleton, gunakan itu untuk menyediakan benih untuk implementasi SecureRandom lainnya yang sepenuhnya deterministik. Desain semacam ini mungkin membutuhkan sedikit pengetahuan.
Maarten Bodewes
@ MaartenBodewes Itu poin bagus. Jika implementasinya salah satu yang menghalangi, menunggu entropi sistem, saya pikir memperlakukannya sebagai singleton dalam aplikasi Anda bukanlah ide yang mengerikan karena sumber yang mendasarinya secara efektif adalah singleton. Tetapi menggunakan satu contoh untuk menabur benih orang lain adalah saran yang bagus, meskipun rumit. Saya tidak yakin, tetapi saya berpikir bahwa penyedia Sun (dan kemudian Oracle) SecureRandomtelah berubah beberapa kali dalam 10 tahun terakhir dalam pertemuan entropinya.
erickson
Saya sangat yakin bahwa itu telah berubah beberapa kali, sangat banyak sehingga saya tidak akan mencoba dan memasukkan semua perubahan dalam komentar ini :). Kecil kemungkinan bahwa lambat SecureRandommasih menjadi masalah, tetapi entropi rendah dalam suatu sistem akan selalu menjadi masalah. Menggunakan singleton akan membuat kode yang sangat berpasangan, yang merupakan desain anti-pola. Karena itu harus digunakan dengan sangat hati-hati; Anda sebaiknya membalik semua referensi dalam kode jika Anda akan memperbaiki masalah.
Maarten Bodewes
2

Sepertinya Anda harus lebih jelas tentang persyaratan RNG Anda. Persyaratan RNG kriptografi terkuat (seperti yang saya mengerti) adalah bahwa bahkan jika Anda tahu algoritma yang digunakan untuk menghasilkan mereka, dan Anda tahu semua nomor acak yang dihasilkan sebelumnya, Anda tidak bisa mendapatkan informasi yang berguna tentang salah satu nomor acak yang dihasilkan dalam masa depan, tanpa menghabiskan jumlah daya komputasi yang tidak praktis.

Jika Anda tidak membutuhkan jaminan penuh keacakan ini, maka mungkin ada tradeoff kinerja yang sesuai. Saya cenderung setuju dengan tanggapan Dan Dyer tentang AESCounterRNG dari Uncommons-Maths, atau Fortuna (salah satu penulisnya adalah Bruce Schneier, seorang ahli kriptografi). Saya tidak pernah menggunakan keduanya tetapi ide-ide itu tampak memiliki reputasi baik pada pandangan pertama.

Saya pikir bahwa jika Anda dapat menghasilkan benih acak awal secara berkala (misalnya sekali per hari atau jam atau apa pun), Anda dapat menggunakan cipher aliran cepat untuk menghasilkan angka acak dari potongan aliran yang berurutan (jika cipher aliran menggunakan XOR maka hanya lewat aliran nol atau ambil bit XOR secara langsung). EStream ECRYPTproyek memiliki banyak informasi yang baik termasuk tolok ukur kinerja. Ini tidak akan mempertahankan entropi di antara titik-titik waktu yang Anda isi ulang, jadi jika seseorang tahu salah satu angka acak dan algoritma yang Anda gunakan, secara teknis dimungkinkan, dengan banyak daya komputasi, untuk memecahkan stream cipher dan tebak kondisi internal untuk dapat memprediksi angka acak di masa depan. Tetapi Anda harus memutuskan apakah risiko dan konsekuensinya cukup untuk membenarkan biaya mempertahankan entropi.

Sunting: inilah beberapa catatan mata kuliah kriptografis di RNG yang saya temukan di internet yang terlihat sangat relevan dengan topik ini.

Jason S
sumber
1
"Fortuna (salah satu penulisnya adalah Bruce Schneier, seorang ahli kriptografi)" - dan yang lainnya adalah Niels Ferguson, seorang ahli dalam kriptografi :-)
Steve Jessop
2

Jika perangkat keras Anda mendukungnya coba gunakan Java RdRand Utility yang saya pembuatnya.

Ini didasarkan pada RDRANDinstruksi Intel dan sekitar 10 kali lebih cepat daripada SecureRandomdan tidak ada masalah bandwidth untuk implementasi volume besar.


Perhatikan bahwa implementasi ini hanya bekerja pada CPU yang memberikan instruksi (yaitu ketika rdrandflag prosesor diatur). Anda harus secara instantiate secara eksplisit melalui RdRandRandom()konstruktor; belum ada yang spesifik yang Providerditerapkan.

pengguna2781824
sumber
3
Anda mungkin ingin membaca people.umass.edu/gbecker/BeckerChes13.pdf dan pastikan untuk tidak pernah hanya menggunakan data Intel RDRAND. Selalu campur dengan beberapa data tak terduga lainnya, seperti output dari stream cRR4 (diunggah dari / dev / urandom dan dengan beberapa KiB pertama dari output yang dibuang karena bias yang diketahui).
mirabilos
+1 mirabilos. Saya pikir RDRANDitu sumber yang bagus, tapi agak tidak bisa dipercaya. Pasti perlu menjadi salah satu masukan dari banyak orang menjadi seorang kolektor (jangan tersinggung oleh David Johnston).
jww
Saya telah memilih, memperbaiki tautan, dan memberikan beberapa informasi latar belakang. Jika Anda tidak setuju, putar kembali hasil edit.
Maarten Bodewes
1

Sesuatu yang lain untuk dilihat adalah properti securerandom.source dalam file lib / security / java.security

Mungkin ada manfaat kinerja untuk menggunakan / dev / urandom daripada / dev / random. Ingat bahwa jika kualitas nomor acak itu penting, jangan buat kompromi yang merusak keamanan.

Diastrofisme
sumber