Категория OWASP: MASVS-CRYPTO: Криптография
Обзор
Генератор псевдослучайных чисел (PRNG) — это алгоритм, который генерирует предсказуемые числовые последовательности на основе начального значения, называемого начальным числом . Числовая последовательность, сгенерированная с помощью PRNG, имеет примерно те же свойства, что и действительно случайная числовая последовательность, но ее создание выполняется быстрее и требует меньше вычислительных затрат.
Другими словами, ГПСЧ имеют более высокие гарантии, чем слабые ГСЧ (например, java.math.Random
) с точки зрения равномерности распределения энтропии, которые имитируют действительно последовательности случайных чисел. Генерация по-настоящему случайных чисел требует специального оборудования и часто выходит за рамки обычной разработки. В этой статье не рассматривается по-настоящему генерация случайных чисел, а основное внимание уделяется только ГПСЧ, поскольку они являются стандартной используемой методологией.
Слабые уязвимости PRNG возникают, когда разработчики используют обычный PRNG для криптографических целей вместо криптографически безопасного PRNG (CSPRNG). К CSPRNG предъявляются более строгие требования, и когда начальное число неизвестно, они должны давать злоумышленнику лишь незначительное преимущество в различении выходной последовательности от фактической случайной последовательности.
Злоумышленники также могут угадать сгенерированную числовую последовательность, когда предсказуемые начальные числа – например, жестко запрограммированные разработчиком – используются для инициализации PRNG или CSPRNG, поскольку злоумышленник может угадать начальное число и, таким образом, предсказать выходные данные, сгенерированные PRNG.
Влияние
Если некриптографически защищенный PRNG используется в контексте безопасности, например аутентификации, злоумышленник может угадать случайно сгенерированные числа и получить доступ к привилегированным данным или функциям.
Смягчения
Общий
- Используйте
java.security.SecureRandom
когда есть проблемы с безопасностью. - Используйте
java.util.Random
для любых других случаев. - Никогда не используйте
Math.random
!
java.security.SecureRandom
Рекомендуется для использования в целях безопасности. Если версия ядра Linux 5.17+ или блокировка потока допустима, подождите, пока накопится достаточно энтропии, прежде чем генерировать случайные числа (т. е. используйте /dev/random
). Для этого вызовите getInstanceStrong()
:
Котлин
val rand = SecureRandom.getInstanceStrong()
Ява
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
}
}
Ява
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.Случайный
Избегайте использования в целях безопасности/аутентификации, допускается использование для чего-либо еще.
Котлин
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)
}
}
Ява
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);
}
}
Ресурсы
Категория OWASP: MASVS-CRYPTO: Криптография
Обзор
Генератор псевдослучайных чисел (PRNG) — это алгоритм, который генерирует предсказуемые числовые последовательности на основе начального значения, называемого начальным числом . Числовая последовательность, сгенерированная с помощью PRNG, имеет примерно те же свойства, что и действительно случайная числовая последовательность, но ее создание выполняется быстрее и требует меньше вычислительных затрат.
Другими словами, ГПСЧ имеют более высокие гарантии, чем слабые ГСЧ (например, java.math.Random
) с точки зрения равномерности распределения энтропии, которые имитируют действительно последовательности случайных чисел. Генерация по-настоящему случайных чисел требует специального оборудования и часто выходит за рамки обычной разработки. В этой статье не рассматривается по-настоящему генерация случайных чисел, а основное внимание уделяется только ГПСЧ, поскольку они являются стандартной используемой методологией.
Слабые уязвимости PRNG возникают, когда разработчики используют обычный PRNG для криптографических целей вместо криптографически безопасного PRNG (CSPRNG). К CSPRNG предъявляются более строгие требования, и когда начальное число неизвестно, они должны давать злоумышленнику лишь незначительное преимущество в различении выходной последовательности от фактической случайной последовательности.
Злоумышленники также могут угадать сгенерированную числовую последовательность, когда предсказуемые начальные числа – например, жестко запрограммированные разработчиком – используются для инициализации PRNG или CSPRNG, поскольку злоумышленник может угадать начальное число и, таким образом, предсказать выходные данные, сгенерированные PRNG.
Влияние
Если некриптографически защищенный PRNG используется в контексте безопасности, например аутентификации, злоумышленник может угадать случайно сгенерированные числа и получить доступ к привилегированным данным или функциям.
Смягчения
Общий
- Используйте
java.security.SecureRandom
когда есть проблемы с безопасностью. - Используйте
java.util.Random
для любых других случаев. - Никогда не используйте
Math.random
!
java.security.SecureRandom
Рекомендуется для использования в целях безопасности. Если версия ядра Linux 5.17+ или блокировка потока допустима, подождите, пока накопится достаточно энтропии, прежде чем генерировать случайные числа (т. е. используйте /dev/random
). Для этого вызовите getInstanceStrong()
:
Котлин
val rand = SecureRandom.getInstanceStrong()
Ява
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
}
}
Ява
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.Случайный
Избегайте использования в целях безопасности/аутентификации, допускается использование для чего-либо еще.
Котлин
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)
}
}
Ява
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);
}
}