Категория OWASP: MASVS-CRYPTO: криптография
Обзор
Генератор псевдослучайных чисел (ГПСЧ) – это алгоритм, который генерирует предсказуемые последовательности чисел на основе начального значения, называемого начальным числом. Последовательность чисел, сгенерированная ГПСЧ, имеет примерно те же свойства, что и последовательность истинно случайных чисел, но создается быстрее и требует меньше вычислительных ресурсов.
Другими словами, ГПСЧ обеспечивают более высокую надежность, чем слабые ГСЧ (например, java.math.Random), с точки зрения равномерности распределения энтропии, которая имитирует истинно случайные последовательности чисел. Для генерации по-настоящему случайных чисел требуется специализированное оборудование, которое обычно не используется при разработке. В этом документе не рассматривается генерация истинно случайных чисел. Мы сосредоточимся на ГПСЧ, поскольку они являются стандартной методологией.
Уязвимости, связанные со слабыми генераторами псевдослучайных чисел, возникают, когда разработчики используют обычные генераторы вместо криптографически защищенных. К CSPRNG предъявляются более строгие требования. Если начальное значение неизвестно, злоумышленник должен иметь лишь незначительное преимущество в дифференциации выходной последовательности от фактической случайной последовательности.
Злоумышленники также могут угадать сгенерированную последовательность чисел, если для инициализации PRNG или CSPRNG используются предсказуемые начальные значения, например заданные разработчиком в коде. В этом случае злоумышленник может угадать начальное значение и, следовательно, предсказать выходные данные, сгенерированные PRNG.
Влияние
Если в контексте безопасности, например при аутентификации, используется криптографически небезопасный генератор псевдослучайных чисел, злоумышленник может угадать случайно сгенерированные числа и получить доступ к конфиденциальным данным или функциям.
Предотвращение атак
Общие
- Используйте
java.security.SecureRandom, если есть угроза безопасности. - Во всех остальных случаях используйте
java.util.Random. - Никогда не используйте
Math.random!
java.security.SecureRandom
Рекомендуется для обеспечения безопасности. На Android SecureRandom.getInstanceStrong() эквивалентно получению SHA1PRNG из AndroidOpenSSL. Она не сопоставляется с блокирующей реализацией /dev/random. Чтобы воспользоваться им,
позвоните по номеру getInstanceStrong().
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
В противном случае в версиях ядра Linux до 5.17, когда блокировка потока при генерации случайных чисел недопустима, конструктор SecureRandom следует вызывать напрямую:
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 и автоматически используется при создании или получении объекта, поэтому нет необходимости явно задавать начальное значение для PRNG. В целом не рекомендуется использовать SecureRandom детерминированным образом (особенно если это приводит к заданию в коде начального значения, которое может увидеть любой, кто декомпилирует приложение). Разработчикам, которым нужно генерировать воспроизводимые псевдослучайные выходные данные, следует использовать более подходящие примитивы, такие как HMAC, HKDF и SHAKE.
java.util.Random
Не рекомендуется использовать для обеспечения безопасности и аутентификации. Подходит для любых других целей.
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);
}
}
Ресурсы
- java.security.SecureRandom
- java.util.Random
- Math.random
- Предсказуемое начальное значение CWE
- Криптографически слабый генератор псевдослучайных чисел (CWE)
- Java Secure Random
- Java Random и SecureRandom
- Как использовать SecureRandom
- Руководство по безопасности генератора псевдослучайных чисел в Python
- Памятка OWASP по криптографическому хранению
- CVE-2013-6386: уязвимость в генераторе псевдослучайных чисел в Drupal
- CVE-2006-3419: уязвимость Tor, связанная со слабым генератором псевдослучайных чисел
- CVE-2008-4102: Predictable Seed in Joomla
- Случайное исправление ядра Linux