Java uygulamaları, kriptografik olarak güçlü sahte rasgele sayı üreteci ( CSPRNG ) kullanarak kriptografik olarak güçlü rasgele değerler üretmek için java.security.SecureRandom sınıfını kullanabilir ve kullanmalıdır . Java.util.Random sınıfının standart JDK uygulamaları kriptografik olarak güçlü kabul edilmez.
Unix benzeri işletim sistemleri /dev/random
, aygıt sürücülerinden ve diğer kaynaklardan toplanan çevresel gürültüye erişen sahte rasgele sayılar sunan özel bir dosyaya sahiptir. Ancak, istenenden daha az entropi olup olmadığını engeller ; /dev/urandom
tipik olarak asla bloke edilmez, çünkü yalancı sayı üreteci tohumu önyüklemeden beri entropi ile tam olarak başlatılmamış olsa bile. Yine de, /dev/arandom
tohum yeterli entropi ile güvenli bir şekilde başlatılana kadar önyüklemeden sonra bloke eden ve daha sonra tekrar bloke etmeyen 3. özel bir dosya var.
Varsayılan olarak, JVM SecureRandom sınıfını kullanarak tohumlar oluşturur /dev/random
, bu nedenle Java kodunuz beklenmedik şekilde engellenebilir . -Djava.security.egd=file:/dev/./urandom
Java işlemini başlatmak için kullanılan komut satırı çağırma seçeneğinde , /dev/urandom
bunun yerine JVM'ye kullanılması bildirilir .
Ekstra /./
, JVM'yi PRNG'nin (Pseudo Random Number Generator) temeli olarak SHA-1 kullanan SHA1PRNG algoritmasını kullanacak gibi görünüyor . /dev/urandom
Belirtildiğinde kullanılan NativePRNG algoritmasından daha güçlüdür .
Son olarak, /dev/urandom
sözde rasgele sayı üreteci, PRNG,/dev/random
efsane ise “gerçek” rasgele sayı üreteci . Bu her ikisi de doğru değildir /dev/random
ve /dev/urandom
aynı CSPRNG (kriptografik olarak güvenli sahte sayı üreteci) tarafından beslenir. Bazı tahminlere göre, sadece kendi havuzları entropi bittiğinde davranış farklıdır: /dev/random
bloklar, /dev/urandom
değil.
Entropinin azalmasına ne dersiniz? Önemli değil.
Kriptografik yapı taşlarımızın birçoğu için “rastgele görünmenin” temel gereksinim olduğu ortaya çıkıyor. Ve eğer bir kriptografik karma çıktı alırsanız, bu rastgele bir dize ayırt edilemez olması gerekir böylece şifreler kabul edecektir. SHA1PRNG algoritmasını kullanmanın nedeni, bir karma işlev ve bir sayaç kullanarak bir tohumla birlikte kullanılmasıdır.
Ne zaman uygulanmalı?
Her zaman söyleyebilirim.
Kaynaklar:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
04/2020 DÜZENLE:
Bir yorum, SecureRandom sınıfının Java 8'deki davranışında bir değişiklikten bahsediyor .
SHA1PRNG ve NativePRNG, java.security dosyasındaki SecureRandom tohum kaynağı özelliklerine uygun şekilde uyması için düzeltildi. (File: /// dev / urandom ve file: / dev /./ urandom kullanarak belirsiz bir geçici çözüm artık gerekli değildir.)
Bu, yukarıda Kaynaklar bölümünde belirtilen testlerle zaten belirtilmişti. Ekstra /./
, Java 8'de SecureRanom tarafından kullanılan algoritmayı NativePRNG'den SHA1PRNG'ye değiştirmek için gereklidir.
Ancak paylaşmak istediğim bazı haberlerim var. Gereğince JEP-273 Java 9 beri SecureRandom sınıfının uyguladığı üç Deterministik Rastgele Bit Jeneratör (DRBG) mekanizmalar tarif NIST 800-90Ar1 . Bu mekanizmalar SHA-512 ve AES-256 kadar güçlü modern algoritmalar uygular.
JDK'nın iki tür SecureRandom uygulaması vardı:
- Bunlardan biri platforma bağlıdır ve yerel çağrılara veya
/dev/{u}random
Unix'te okuma veya Windows'ta CryptoAPI kullanma gibi işletim sistemlerine dayanmaktadır . Linux ve Windows'un en son sürümleri zaten DRBG'yi destekliyor, ancak eski sürümler ve gömülü sistemler desteklemiyor olabilir .
- Diğer tür, onaylanmış DRBG mekanizmaları tarafından kullanılan algoritmalar kadar güçlü olmayan eski bir SHA1 tabanlı RNG uygulaması kullanan saf bir Java uygulamasıdır.
Bu arada Java 13 Güvenlik Geliştirici Kılavuzu hala okunuyor
Linux ve macOS'ta java.security'deki entropi toplama cihazı file:/dev/urandom
veya olarak ayarlanırsa file:/dev/random
, SHA1PRNG yerine NativePRNG tercih edilir. Aksi takdirde, SHA1PRNG tercih edilir.
Yeni DRBG mekanizmalarının önceki PRNG'lerle birlikte nasıl oynadığını açıklığa kavuşturmak için, AdoptOpenJDK (build 13.0.2 + 8) ile macOS (Darwin) üzerinde bazı testler yapıyorum. Sonuçlar burada:
file: / dev / random
Sağlayıcılar için tercih sırası:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
file: / dev / urandom
Sağlayıcılar için tercih sırası:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
file: / dev /./ urandom
Sağlayıcılar için tercih sırası:
SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG
Sonuç:
Beklenmedik bir şekilde bloke kodu almaktan kaçınırken kullanılan platform ne olursa olsun kullanılabilir -Djava.security.egd=file:/dev/./urandom
en güçlü SecureRandom uygulamasını kullanarak emin olmak için kullanmanızı tavsiye ederim .