OWASP-Kategorie: MASVS-CRYPTO: Cryptography
Übersicht
Ein Pseudozufallszahlengenerator (Pseudorandom Number Generator, PRNG) ist ein Algorithmus, der auf einem Startwert, dem sogenannten Seed , vorhersagbare Zahlenfolgen generiert. Eine von einem PRNG generierte Zahlenfolge hat ungefähr dieselben Eigenschaften wie eine echte Zufallszahlenfolge, ist aber schneller und weniger rechenintensiv zu erstellen.
Mit anderen Worten: PRNGs bieten im Hinblick auf die Gleichmäßigkeit der Entropieverteilung eine höhere Sicherheit als schwache Zufallszahlengeneratoren (z.B. java.math.Random), die echte Zufallszahlenfolgen nachahmen. Die Erzeugung echter Zufallszahlen erfordert spezielle Geräte und geht oft über den Rahmen der normalen Entwicklung hinaus. In diesem Dokument wird die Erzeugung echter Zufallszahlen nicht behandelt, sondern nur auf PRNGs eingegangen, da sie die Standardmethode sind.
Schwachstellen bei PRNGs treten auf, wenn Entwickler einen regulären PRNG für kryptografische Zwecke verwenden, anstatt einen kryptografisch sicheren PRNG (Cryptographically-Secure PRNG, CSPRNG). Für CSPRNGs gelten strengere Anforderungen. Wenn der Seed unbekannt ist, dürfen sie einem Angreifer nur einen unbedeutenden Vorteil bei der Unterscheidung einer Ausgabefolge von einer tatsächlichen Zufallsfolge verschaffen.
Angreifer können die generierte Zahlenfolge möglicherweise auch erraten, wenn vorhersagbare Seeds verwendet werden, um einen PRNG oder CSPRNG zu initialisieren. Das ist beispielsweise der Fall, wenn der Seed vom Entwickler fest codiert wurde. Der Angreifer kann den Seed erraten und so die vom PRNG generierte Ausgabe vorhersagen.
Auswirkungen
Wenn ein nicht kryptografisch sicherer PRNG in einem Sicherheitskontext wie der Authentifizierung verwendet wird, kann ein Angreifer die zufällig generierten Zahlen möglicherweise erraten und Zugriff auf vertrauliche Daten oder Funktionen erhalten.
Gegenmaßnahmen
Allgemein
- Verwenden Sie
java.security.SecureRandom, wenn Sicherheitsrisiken bestehen. - Verwenden Sie
java.util.Randomin allen anderen Fällen. - Verwenden Sieniemals .
Math.random
java.security.SecureRandom
Empfohlen für Sicherheitsanwendungen. Wenn die Linux-Kernel-Version 5.17 oder höher ist oder das Blockieren des Threads akzeptabel ist, warten Sie, bis genügend Entropie angesammelt ist, bevor Sie die Zufallszahlen generieren (d.h. verwenden Sie /dev/random). Rufen Sie dazu getInstanceStrong() auf:
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
Andernfalls sollte bei Linux-Kernelversionen vor 5.17, wenn das Blockieren des Threads beim Generieren von Zufallszahlen nicht akzeptabel ist, der Konstruktor SecureRandom direkt aufgerufen werden:
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 ruft den Standardsamen aus /dev/urandom ab und wird automatisch verwendet, wenn das Objekt erstellt oder abgerufen wird. Daher ist es nicht erforderlich, den PRNG explizit zu initialisieren. Im Allgemeinen wird von jeder deterministischen Verwendung von SecureRandom abgeraten, insbesondere wenn dies dazu führt, dass ein Seed-Wert fest codiert wird, der von jedem, der die App dekompiliert, eingesehen werden kann. Entwickler, die reproduzierbare pseudozufällige Ausgaben generieren möchten, sollten besser geeignete Primitive wie HMAC, HKDF und SHAKE verwenden.
java.util.Random
Vermeiden Sie die Verwendung für Sicherheits-/Authentifizierungszwecke. Für alle anderen Zwecke ist die Verwendung akzeptabel.
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);
}
}
Ressourcen
- java.security.SecureRandom
- java.util.Random
- Math.random
- Vorhersagbarer Seed CWE
- Kryptografisch schwacher PRNG CWE
- Java Secure Random
- Java Random im Vergleich zu SecureRandom
- SecureRandom verwenden
- Sicherheitsleitfaden für Python-PRNG
- OWASP Cryptographic Storage Cheat Sheet
- CVE-2013-6386: Schwachstelle durch schwachen PRNG in Drupal
- CVE-2006-3419: Schwachstelle durch schwachen PRNG in Tor
- CVE-2008-4102: Vorhersagbarer Seed in Joomla
- Zufälliger Patch für den Linux-Kernel