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