Где взять надежный источник энтропии (байт реальной случайности [])?

В настоящее время я ищу способ увеличить качество случайности в моем приложении Android (карточная игра). Ранее предполагалось, что для моей ситуации (52! Перестановки) требуется не менее 226 бит энтропии (226 случайных битов).

Я планирую использовать этот byte[] как семя для SecureRandom:

SecureRandom random = new SecureRandom();
random.setSeed(/* insert seed here, byte[] */)

Вопрос в том - Где я могу надежно получить случайные биты в таком количестве (не менее 226 бит) на Android, желательно без каких-либо разрешений и без интернета. Кроме того, он должен работать независимо от устройства и уровня API.

Пожалуйста, не повторяйте android ярлык в заглавие.

Phantômaxx 10.08.2018 15:19
«... желательно без каких-либо разрешений и без интернета ...» Я очень сомневаюсь, что сможете. Вам потребуются разрешения, чтобы использовать микрофон для улавливания окружающего шума, например, или Интернет, чтобы использовать random.org или аналогичный ...
T.J. Crowder 10.08.2018 15:20

@KlingKlang - Но я ищу ответ специально для Android. Неправильно ли это заявить в названии?

Sergei Emelianov 10.08.2018 15:20

НЕТ. ярлык достаточно.

Phantômaxx 10.08.2018 15:21

@KlingKlang - Хорошо, спасибо за руководство ..

Sergei Emelianov 10.08.2018 15:22

наверное глупо, а как насчет двух экземпляров UUID.randomUUID().toString().getBytes();?

Eugene 10.08.2018 15:22

Не за что....

Phantômaxx 10.08.2018 15:23

Думаю, для игры это практически не актуально. Чтобы увидеть повтор, нужно сыграть в миллиарды игр.

Henry 10.08.2018 15:24
SecureRandom использует /dev/random в Linux и, скорее всего, Android.
Peter Lawrey 10.08.2018 15:24

@Eugene - Это будет псевдослучайная, а не настоящая энтропия.

T.J. Crowder 10.08.2018 15:24

@ T.J. Crowder хороший замечание! Спасибо

Eugene 10.08.2018 15:25

Какой смысл иметь "настоящую" случайность? Особенно в игре (связанной? stackoverflow.com/questions/426821/…)

zapl 10.08.2018 15:33
3
12
308
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не имея возможности получить доступ к микрофону (для чего потребуются разрешения) или захватить байты из random.org (для чего потребуется Интернет), единственное, что я могу придумать, это сам пользователь: представьте пустой квадрат, по которому пользователь перемещает палец. , инструктируя их делать это как можно более случайным образом, в идеале в течение нескольких секунд, и использовать эти сенсорные данные. (Кажется, я припоминаю приложение, которое я использовал   - TrueCrypt?   - это делало.) Вы можете даже добавить некоторую псевдослучайность поверх их человеческой случайности, чтобы попытаться избежать того, чтобы люди играли в систему с чрезвычайно точными повторяемыми движениями.

Если вы немного ослабите свои требования, вы, вероятно, сможете получить неплохую энтропию от микрофона (окружающий шум) и / или акселерометра. И, конечно же, если вы запрашиваете доступ к сети, вы можете загружать действительно случайные данные из http://random.org.

Если они не заботятся о разрешениях, получение байтового потока с микрофона или данных ACCELEROMETER, а затем добавление его к псевдослучайному числу, похоже, сработает.

Josh White 10.08.2018 15:31

Очень хороший момент, возможно, я мог бы генерировать случайные байты на основе действий в предыдущем раунде игры ..

Sergei Emelianov 10.08.2018 15:34
Ответ принят как подходящий

На Java 8+ вы можете использовать

SecureRandom rand = SecureRandom.getInstanceStrong();

Чтобы получить самую сильную случайность, доступную на вашей платформе. Чтобы быть явным, вы можете использовать

SecureRandom rand = SecureRandom.getInstance("NativePRNGBlocking");

которые используют энтропию /dev/random в Linux-подобных системах. Однако я ожидаю, что он выйдет из строя, если он недоступен.

https://www.synopsys.com/blogs/software-security/proper-use-of-javas-securerandom/


Альтернативно

Вы можете создать случайность на основе ввода пользователя, взяв SHA256 или выше из System.nanoTime() предыдущих событий.

Другие вопросы по теме