Apakah utas SecureRandom aman?

103

Apakah SecureRandombenang aman? Artinya, setelah menginisialisasi, dapatkah akses ke nomor acak berikutnya diandalkan agar thread safe? Memeriksa kode sumber tampaknya menunjukkan bahwa memang benar, dan laporan bug ini tampaknya menunjukkan bahwa kurangnya dokumentasinya sebagai thread safe adalah masalah javadoc. Adakah yang mengonfirmasi bahwa ini memang thread safe?

Yishai
sumber

Jawaban:

108

Ya itu. Itu meluas Random, yang selalu memiliki implementasi threadsafe de facto , dan, dari Java 7, secara eksplisit menjamin keamanan thread.

Jika banyak utas menggunakan satu SecureRandom, mungkin ada perselisihan yang merusak kinerja. Di sisi lain, menginisialisasi sebuah SecureRandominstance bisa relatif lambat. Apakah yang terbaik untuk membagikan RNG global, atau membuat yang baru untuk setiap utas akan bergantung pada aplikasi Anda. The ThreadLocalRandomkelas dapat digunakan sebagai pola untuk memberikan solusi yang mendukung SecureRandom.

erickson
sumber
3
Terima kasih atas pembaruannya. Anehnya, bug tersebut ditandai ditutup sebagai "tidak akan diperbaiki." Tapi mereka tetap memperbaikinya. Baiklah, saya tidak iri dengan ukuran database bug mereka.
Yishai
4
menginisialisasi SecureRandomtidak hanya bisa lambat, tetapi juga berpotensi hang karena entropi hilang
Walter Tross
8
Harap diingat bahwa ThreadLocalRandom sangat mudah diretas, jadi jika Anda berencana untuk mengekspos nilai yang dihasilkan ke dunia, gunakan SecureRandom sebagai gantinya jazzy.id.au/default/2010/09/20/…
walv
2
Saya akan mengambil risiko di sini dan mengatakan jawaban ini salah. Kontrak untuk Random, yang menjamin keamanan thread, tidak mengikat subclass. Tentu saja semua properti lain dari Random didokumentasikan tidak mengikat pada subclass, jadi saya tidak mengerti mengapa keamanan thread harus diasumsikan.
Presiden James K. Polk
2
@JamesKPolk Kegagalan mempertahankan properti supertipe akan melanggar prinsip substitusi.
erickson
11

Implementasi saat ini SecureRandomadalah thread safe, khususnya dua metode mutasi nextBytes(bytes[])dan setSeed(byte[])disinkronkan.

Sejauh yang saya tahu, semua metode mutasi pada akhirnya diarahkan melalui kedua metode tersebut, dan SecureRandommenimpa beberapa metode Randomuntuk memastikannya. Yang berfungsi tetapi bisa rapuh jika penerapannya diubah di masa mendatang.

Solusi terbaik adalah menyinkronkan SecureRandominstans secara manual terlebih dahulu. Ini berarti setiap tumpukan panggilan akan memperoleh dua kunci pada objek yang sama, tetapi biasanya sangat murah pada JVM modern. Artinya, tidak banyak salahnya menyinkronkan diri Anda secara eksplisit. Sebagai contoh:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }
Matt Puyuh
sumber
3
Setidaknya di JDK 10, SecureRandom didasarkan pada penyedia dan memeriksa apakah penyedia aman untuk thread, hanya menyinkronkan jika tidak, di nextBytes.
nafg
java.security.SecureRandom#nextBytesdi Java 8 tidak disinkronkan. Bisakah Anda menjelaskan dalam versi Java apakah Anda menemukan sinkronisasi #nextBytes?.
Jaime Hablutzel