Opsi java.security.egd untuk apa?

23

Dalam proyek yang sedang saya kerjakan, aplikasi diluncurkan menggunakan perintah yang mirip dengan ini:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

Saya belum pernah melihat java.security.egdopsi sebelumnya. Mencari sedikit, tampaknya digunakan untuk mengkonfigurasi pembuatan angka acak dalam aplikasi Java.

Apakah tepat? Kapan seharusnya diterapkan?

davioooh
sumber

Jawaban:

30

Aplikasi Java dapat dan harus menggunakan kelas java.security.SecureRandom untuk menghasilkan nilai acak yang kuat secara kriptografis dengan menggunakan pseudo-random number generator ( CSPRNG ) yang kuat secara kriptografis . Implementasi JDK standar dari kelas java.util.Random tidak dianggap kuat secara kriptografis.

Sistem operasi seperti Unix memiliki /dev/random, file khusus yang melayani nomor acak semu mengakses kebisingan lingkungan yang dikumpulkan dari driver perangkat dan sumber lainnya. Namun, itu memblokir jika ada lebih sedikit entropi yang tersedia daripada yang diminta ; /dev/urandombiasanya tidak pernah memblokir, bahkan jika seed generator nomor pseudorandom tidak sepenuhnya diinisialisasi dengan entropi sejak booting. Masih ada file khusus ke-3, /dev/arandomyang memblokir setelah boot sampai benih telah diinisialisasi dengan aman dengan cukup entropi, dan kemudian tidak pernah memblokir lagi.

Secara default, JVM menggunakan kelas SecureRandom/dev/random , sehingga kode Java Anda dapat memblokir secara tidak terduga . Opsi -Djava.security.egd=file:/dev/./urandomdalam permintaan baris perintah yang digunakan untuk memulai proses Java memberitahu JVM untuk menggunakannya /dev/urandom.

Kelebihan tersebut /./tampaknya membuat JVM menggunakan algoritma SHA1PRNG yang menggunakan SHA-1 sebagai dasar dari PRNG (Pseudo Random Number Generator). Ini lebih kuat dari algoritma NativePRNG yang digunakan saat /dev/urandomditentukan.

Akhirnya, ada mitos yang /dev/urandommerupakan generator nomor acak semu, sebuah PRNG, sementara itu /dev/randomadalah generator nomor acak "benar" . Ini tidak benar, keduanya /dev/randomdan /dev/urandomdiberi makan oleh CSPRNG yang sama (generator nomor pseudorandom yang aman secara kriptografis). Hanya perilaku ketika kumpulan masing-masing kehabisan entropi, menurut beberapa perkiraan, berbeda: /dev/randomblok, sementara /dev/urandomtidak.

Bagaimana dengan entropi yang hampir habis? Itu tidak masalah.

Ternyata "tampak acak" adalah persyaratan dasar untuk banyak blok bangunan kriptografi kami. Dan jika Anda mengambil output dari hash kriptografi, itu harus dibedakan dari string acak sehingga cipher akan menerimanya. Itulah alasan menggunakan algoritma SHA1PRNG, karena menggunakan fungsi hash dan penghitung, bersama dengan seed.

Kapan seharusnya diterapkan?

Saya selalu mengatakan demikian.

Sumber:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


EDIT 04/2020:

Sebuah komentar menyebutkan perubahan perilaku kelas SecureRandom di Java 8.

SHA1PRNG dan NativePRNG diperbaiki untuk menghormati dengan benar properti sumber seed SecureRandom di file java.security. (Solusi tidak jelas menggunakan file: /// dev / urandom dan file: / dev /./ urandom tidak lagi diperlukan.)

Ini sudah ditunjukkan oleh tes yang dirujuk pada bagian Sumber di atas. Ekstra /./diperlukan untuk mengubah algoritma yang digunakan oleh SecureRanom di Java 8 dari NativePRNG ke SHA1PRNG.

Namun, saya punya beberapa berita yang ingin saya bagikan. Sesuai JEP-273 , sejak Java 9 kelas SecureRandom mengimplementasikan tiga mekanisme Deterministic Random Bit Generator (DRBG) yang dijelaskan dalam NIST 800-90Ar1 . Mekanisme ini menerapkan algoritma modern sekuat SHA-512 dan AES-256.

JDK memiliki dua jenis implementasi SecureRandom :

  • Satu tergantung platform dan didasarkan pada panggilan asli atau perangkat OS seperti membaca /dev/{u}randomdi Unix atau menggunakan CryptoAPI di Windows. Rilis terbaru dari Linux dan Windows sudah mendukung DRBG, tetapi rilis yang lebih lama dan sistem embedded mungkin tidak .
  • Jenis lainnya adalah implementasi Java murni yang menggunakan implementasi RNG berbasis SHA1 yang lebih tua, yang tidak sekuat algoritma yang digunakan oleh mekanisme DRBG yang disetujui.

Sementara itu , Panduan Pengembang Keamanan Java 13 masih membaca

Di Linux dan macOS, jika perangkat pengumpulan entropi di java.security diatur ke file:/dev/urandomatau file:/dev/random, maka NativePRNG lebih disukai daripada SHA1PRNG. Kalau tidak, SHA1PRNG lebih disukai.

Untuk memperjelas bagaimana mekanisme DRBG baru bermain bersama dengan PRNG sebelumnya, saya menjalankan beberapa tes pada macOS (Darwin) dengan AdoptOpenJDK (build 13.0.2 + 8). Inilah hasilnya:

file: / dev / random
Urutan preferensi untuk penyedia:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev / urandom
Urutan preferensi untuk penyedia:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev /./ urandom
Urutan preferensi untuk penyedia:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

Kesimpulan:

Saya akan merekomendasikan menggunakan -Djava.security.egd=file:/dev/./urandomuntuk memastikan memanfaatkan implementasi SecureRandom terkuat yang tersedia terlepas dari platform yang digunakan sambil menghindari kode diblokir secara tak terduga.

dbaltor
sumber
1
Pada Java 8, "solusi tidak jelas" dari ekstra ./ dalam nama file tidak diperlukan lagi, jadi Anda bisa menggunakan "/ dev / urandom", lihat: docs.oracle.com/javase/8/docs / technotes / pemandu / keamanan / ...
Kamal
Terima kasih telah memperbarui jawabannya (khususnya tentang perubahan di Java 9 dan 13). Menurut pemahaman saya, pada Java 8 pengaturan "perangkat pengumpulan entropi" ke / dev / urandom atau /dev/./urandom akan menghasilkan hasil yang persis sama, jika tidak maka perbaikannya tidak masuk akal. Dari perspektif OS, mereka menunjuk ke file identik yang sama, sehingga seharusnya tidak mempengaruhi Java (itu terjadi sebelum perbaikan, tapi itu bug, bukan fitur yang dimaksudkan). Karenanya pernyataan Anda "Ekstra /./ diperlukan untuk memengaruhi pemilihan PRNG." seharusnya tidak lagi benar, mulai dari Jawa 8.
Kamal
Terima kasih @Kamal atas komentar Anda. Frasa saya sebelumnya "Pilihan PRNG" tidak cukup jelas. Saya telah mengulanginya untuk menjelaskan bahwa saya sedang berbicara tentang algoritma yang digunakan: NativePRNG atau SHA1PRNG. Penggunaan /dev/urandommemilih NativePRNG yang diumpankan oleh /dev/urandomsementara /dev/./urandommengambil SHA1PRNG ke atas (juga diumpankan oleh /dev/urandom) saat menggunakan Java 8. Dari Java 9 dan seterusnya, DRBG diutamakan ketika /dev/./urandomsumber ditentukan.
dbaltor
1

Ini tidak lagi diperlukan jika Anda menggunakan JDK 8 atau lebih tinggi

Masalah ini telah diperbaiki oleh Java dan berikut adalah beberapa tautan

Garis besar

SHA1PRNG dan NativePRNG diperbaiki untuk menghormati dengan benar properti sumber seed SecureRandom di file java.security. (Solusi tidak jelas menggunakan file: /// dev / urandom dan file: / dev /./ urandom tidak lagi diperlukan.)

Untuk info lebih lanjut (cari secara acak di halaman):

https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html

https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

Venu Madhav
sumber
Saya tidak percaya ini benar. Untuk latar belakang: tersesystems.com/blog/2015/12/17/... Perbaikan di Java 8 hanya mengatakan bahwa mereka sekarang menghormati properti sumber seed SecureRandom di file java.security. Tetapi secara default yang masih mengandung: securerandom.source = file: / dev / random The "obscure workaround" mengacu pada tambahan ./ dalam nama file, juga disebutkan oleh jawaban yang diterima (dan paling banyak dipilih) di sini.
Kamal
The "jelas solusi" itu hanya diperlukan dalam keadaan tertentu, lihat: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal
@Kamal Tautan yang Anda kirim merujuk ke Java 6 dan sebelumnya,
Venu Madhav
Itulah intinya, itu diperbaiki di Jawa 8. Menurut laporan bug, "solusi tidak jelas" (menambahkan ekstra ./ dalam nama file) diperlukan setelah Java 1.4.2 dan hingga 6. Saya berasumsi di Java 7 juga, kalau tidak itu tidak akan disebutkan sebagai diperbaiki di Java 8. Pengaturan / dev / urandom bukan / dev / random masih diperlukan, jika Anda ingin menggunakan perangkat non-blocking.
Kamal
0

Ini terkait dengan perbedaan linux /dev/randomdan /dev/urandomgenerator angka acak.

Diambil dari tautan ini

Java Bug 6202721 menyatakan bahwa java.security.SecureRandom menggunakan / dev / random daripada / dev / urandom bahkan jika / dev / urandom ditentukan karena pada saat itu (sekitar 2004) / dev / urandom tidak berfungsi dengan benar. Bug tidak pernah dibalik sekarang karena / dev / urandom berfungsi dengan baik. Oleh karena itu, Anda harus memalsukannya dengan mengaburkan pengaturan dengan menggunakan /dev/./urandom untuk memaksa penggunaan SHA1PRNG daripada / dev / acak.

Untuk menjawab pertanyaan Anda

Kapan seharusnya diterapkan?

Berdasarkan tautan di atas, itu adalah sesuatu yang unik untuk Java versi 5 dan berikutnya yang dihasilkan dari masalah dengan / dev / urandom di sistem Linux pada tahun 2004.

Ruelos Joel
sumber
Mungkin ada kesalahan ketik dalam artikel itu, karena Java Bug 6202721 sebenarnya menyatakan "Ini adalah masalah jika / dev / urandom dipilih karena / dev / random tidak berfungsi dengan benar.". Oleh karena itu kesimpulan Anda "dihasilkan dari masalah dengan / dev / urandom" tidak benar. Lihat jawaban yang diterima untuk penjelasan tentang memilih / dev / urandom daripada default (/ dev / random). Itu ide yang bagus dalam banyak kasus.
Kamal