OWASP kategorisi: MASVS-CRYPTO: Kriptografi
Genel Bakış
Sözde rastgele sayı üreteci (PRNG), başlangıç noktası adı verilen bir başlangıç değerine dayalı olarak tahmin edilebilir sayı dizileri oluşturan bir algoritmadır. PRNG tarafından oluşturulan sayı dizisi, yaklaşık olarak tamamen rastgele bir sayı dizisiyle aynı özelliklere sahiptir ancak oluşturulması daha hızlıdır ve daha az hesaplama maliyetlidir.
Diğer bir deyişle, PRNG'ler, entropi dağılımının eşitliği açısından zayıf RNG'lerden (ör. java.math.Random) daha fazla güvenceye sahiptir ve gerçekten rastgele sayı dizilerini taklit eder. Gerçekten rastgele sayı üretimi için özel ekipman gerekir ve bu işlem genellikle normal geliştirme kapsamı dışındadır. Bu belge, gerçekten rastgele sayı oluşturmayı kapsamaz ve yalnızca kullanılan standart metodoloji oldukları için PRNG'lere odaklanır.
Geliştiriciler, kriptografik amaçlar için kriptografik açıdan güvenli bir PRNG (CSPRNG) yerine normal bir PRNG kullandığında zayıf PRNG güvenlik açıkları oluşur. CSPRNG'ler daha katı şartlara sahiptir ve başlangıç değeri bilinmediğinde, saldırgana yalnızca bir çıkış dizisini gerçek bir rastgele diziden ayırt etme konusunda önemsiz bir avantaj sağlamalıdır.
Geliştirici tarafından sabit kodlanmış olanlar gibi tahmin edilebilir başlangıç değerleri, PRNG veya CSPRNG başlatmak için kullanıldığında saldırganlar, oluşturulan sayı dizisini de tahmin edebilir. Bunun nedeni, saldırganın başlangıç değerini tahmin edip PRNG tarafından oluşturulan çıktıyı tahmin edebilmesidir.
Etki
Kimlik doğrulama gibi bir güvenlik bağlamında kriptografik olarak güvenli olmayan bir PRNG kullanılırsa saldırgan, rastgele oluşturulan sayıları tahmin edebilir ve ayrıcalıklı verilere veya özelliklere erişebilir.
Çözümler
Genel
java.security.SecureRandomsimgesini güvenlik açısından sonuçlar olduğunda kullanın.- Diğer tüm durumlarda
java.util.Randomkullanın. Math.randomasla kullanmayın.
java.security.SecureRandom
Güvenlik amaçlı kullanım için önerilir. Linux çekirdek sürümü 5.17 veya daha yeniyse ya da iş parçacığının engellenmesi kabul edilebilir bir durumsa rastgele sayıları oluşturmadan önce yeterli entropinin birikmesini bekleyin (ör. /dev/random kullanın). Bunu yapmak için getInstanceStrong() işlevini çağırın:
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
Aksi takdirde, Linux çekirdeğinin 5.17'den önceki sürümlerinde rastgele sayılar oluşturulurken iş parçacığının engellenmesi kabul edilemez olduğunda SecureRandom oluşturucusu doğrudan çağrılmalıdır:
Kotlin
import java.security.SecureRandom
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = SecureRandom()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
// Use rand_int for security & authentication
}
}
Java
import java.security.SecureRandom;
public class generateRandom {
public static void main(String args[])
{
// Create instance of SecureRandom class
SecureRandom rand = new SecureRandom();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
// Use rand_int for security & authentication
}
}
SecureRandom, /dev/urandom'den varsayılan başlangıç değerini alır ve nesne oluşturulduğunda veya alındığında otomatik olarak kullanılır. Bu nedenle, PRNG'yi açıkça başlatmaya gerek yoktur. Genel olarak, SecureRandom
değerinin deterministik kullanımı önerilmez (özellikle bu durum, uygulamayı derlemeden çıkaran herkesin görebileceği bir başlangıç değerinin sabit kodlanmasına yol açıyorsa). Yeniden üretilebilir sözde rastgele çıkış oluşturmak isteyen geliştiriciler, HMAC, HKDF ve SHAKE gibi daha uygun temel öğeleri kullanmalıdır.
java.util.Random
Güvenlik / kimlik doğrulama amaçları için kullanmayın. Diğer amaçlar için kullanılabilir.
Kotlin
import java.util.Random
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = Random()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
}
}
Java
import java.util.Random;
public class generateRandom {
public static void main(String args[])
{
// Create instance of Random class
Random rand = new Random();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
}
}
Kaynaklar
- java.security.SecureRandom
- java.util.Random
- Math.random
- Öngörülebilir Seed CWE
- Kriptografik olarak zayıf PRNG CWE'si
- Java Secure Random
- Java Random ve SecureRandom karşılaştırması
- SecureRandom nasıl kullanılır?
- Python PRNG güvenlik kılavuzu
- OWASP Cryptographic Storage Cheat Sheet
- CVE-2013-6386: Drupal'daki zayıf PRNG güvenlik açığı
- CVE-2006-3419: Tor'daki zayıf PRNG güvenlik açığı
- CVE-2008-4102: Joomla'da Tahmin Edilebilir Tohum
- Linux çekirdeği rastgele yama