Як боротися з повільним генератором SecureRandom?


165

Якщо ви хочете криптографічно сильних випадкових чисел на Java, ви використовуєте SecureRandom. На жаль, SecureRandomможе бути дуже повільним. Якщо він використовується /dev/randomв Linux, він може блокувати очікування достатньої ентропії для нарощування. Як уникнути штрафу за виконання?

Хтось використовував нечасті математики як рішення цієї проблеми?

Чи може хтось підтвердити, що ця проблема продуктивності була вирішена в JDK 6?


Здається, це пов'язано з повільністю SecureRandom.generateSeed () . Існує відхилений дефект, що пояснює повільність та обхід
AlikElzin-kilaka

Перевірте / dev / urandom (не / dev / random). Подумайте, як тільки отримати генератор випадкових чисел від урануму, якщо є проблема з блокуванням.
jcalfee314

Вікна , пов'язані: stackoverflow.com/questions/49322948 / ...
patrikbeno

Відповіді:


79

Якщо ви хочете правдивих випадкових даних, то, на жаль, доведеться їх чекати. Сюди входить насіння для SecureRandomPRNG. Нечасті математики не можуть зібрати справжні випадкові дані швидше SecureRandom, хоча вони можуть підключитися до Інтернету, щоб завантажити насінні дані з певного веб-сайту. Я здогадуюсь, що це навряд чи буде швидше, ніж /dev/randomтам, де це є.

Якщо ви хочете PRNG, зробіть щось подібне:

SecureRandom.getInstance("SHA1PRNG");

Які рядки підтримуються, залежить від SecureRandomпостачальника послуг SPI, але ви можете перерахувати їх за допомогою Security.getProviders()та Provider.getService().

Sun любить SHA1PRNG, тому він широко доступний. Це не особливо швидко, оскільки їздять PRNG, але PRNG будуть просто стискати числа, не блокуючи фізичне вимірювання ентропії.

Виняток полягає в тому, що якщо ви не зателефонували setSeed()до отримання даних, PRNG видасть себе один раз при першому дзвінку next()або nextBytes(). Зазвичай це робиться за допомогою досить невеликої кількості правдивих випадкових даних із системи. Цей виклик може блокуватись, але зробить ваше джерело випадкових чисел набагато безпечнішим, ніж будь-який варіант "хеш поточного часу разом з PID, додайте 27 та сподівайтеся на найкраще". Якщо все, що вам потрібно, це випадкові числа для гри, або якщо ви хочете, щоб потік повторювався в майбутньому, використовуючи одне і те ж насіння для тестування, небезпечне насіння все ще корисне.


Нечасто Maths завантажує дані лише з Інтернету для висіву насіння, вони не повертають цих випадкових даних при генерації випадкових чисел.
Дан Дайер

Те саме з SecureRandom - / dev / urandom призначений лише для висіву насіння.
AviD

Так. Коли запитуючий каже: "Якщо ви хочете, щоб випадкове число ви використовували SecureRandom - це може бути повільним", я подумав, що, можливо, він використовує getSeed для всього і злив свій пул ентропії. Виправлення не в тому, щоб отримати JDK 6, це використовувати SecureRandom так, як було призначено ;-)
Стів Джессоп,

@Dan Dyer - я виправив свій коментар про нечасті математики. Я переглянув вашу сторінку, тому я знав, що під "випадковими числами" я маю на увазі "для її насіння", а не "для повернення до користувача". Але ти абсолютно прав, що це не те, що я сказав ...
Стів Джессоп,

"вона широко доступна". Чи не він включений до кожного сумісного JDK? Це в списку стандартних імен безпеки Java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Шон Рейлі

176

Ви повинні мати можливість вибрати швидший, але трохи менш безпечний / dev / urandom в Linux, використовуючи:

-Djava.security.egd=file:/dev/urandom

Однак це не працює з Java 5 та новішими версіями ( Java Bug 6202721 ). Запропонований обхід полягає у використанні:

-Djava.security.egd=file:/dev/./urandom

(зверніть увагу на додаткове /./)


24
Зауважте, що у звіті про помилку Java написано "Не дефект". Іншими словами, незважаючи на те, що за замовчуванням є /dev/urandom, Sun розглядає це як магічний рядок і /dev/randomвсе одно використовує , тому вам доведеться підробити це. Коли file:URL-адреса не file:URL-адреса? Щоразу, коли Сонце вирішить, що це не так :-(
Джим Гаррісон

6
Щойно витративши багато часу на дослідження цього, здається, що звичайне налаштування, навіть якщо воно file:/dev/urandomвстановлено у файлі java.security -Djava.security.egdабо в securerandom.sourceньому, /dev/random/все ще читається щоразу SecureRandom.getSeed()(або setSeed()називається). Обхід із file:/dev/./urandomрезультатами взагалі не читається /dev/random(підтверджено страйком)
мат b

7
/dev/urandomне менш безпечний, ніж /dev/randomколи реалізований із сучасним CSPRNG: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo

Я думаю, що головний страх /dev/urandom/полягає в тому, що трапляється, якщо ви використовуєте його для створення секретів на новій техніці поза коробкою, яка може бути у досить передбачуваному стані. /dev/urandom/не заблокує ентропію, хоча це один із випадків, коли вам слід. Ситуація ще гірша, якщо секрет зберігається, наприклад, якщо перше, що робить ваш пристрій під час першого завантаження, - це генерувати пара публічно-приватних ключів. Поза цих страшних ситуацій добро /dev/urandomкраще, ніж використання загальних SecureRandomалгоритмів.
Стів Джессоп

1
Який з них правильний? -Djava.security.egd = файл: / dev /./ urandom або файл: /// dev / urandom @mattb
Aarish Ramesh

35

Для Linux реалізацією за замовчуванням SecureRandomє NativePRNG(вихідний код тут ), яка, як правило, дуже повільна. У Windows за замовчуванням є те SHA1PRNG, що, як зазначали інші, ви також можете використовувати в Linux, якщо чітко вказати його.

NativePRNGвідрізняється від AESCounterRNG від SHA1PRNGматематики та Uncommons Maths тим, що він постійно отримує ентропію від операційної системи (шляхом читання з /dev/urandom). Інші PRNG не отримують додаткової ентропії після висіву насіння.

AESCounterRNG приблизно в 10 разів швидше, ніж SHA1PRNGIIRC сам по собі в два-три рази швидше NativePRNG.

Якщо вам потрібна швидша PRNG, яка набуває ентропії після ініціалізації, подивіться, чи можна знайти реалізацію Java Fortuna . Основний PRNG реалізації Fortuna ідентичний тому, який використовує AESCounterRNG, але також існує складна система об'єднання ентропії та автоматичного повторного повторного пересідання.


Це посилання не працює. unsmons-maths.dev.java.net/nonav/api/org/uncommons/maths/… . Чи десь я це бачу?
УВМ

@Unni Щойно оновив посилання. Зверніть увагу, що претензії на виконання, які я висловив у цій відповіді, більше не можуть бути дійсними. Я думаю, що в останніх версіях Java все може покращитися, і між платформами можуть бути відмінності у продуктивності (наприклад, Windows проти Liux).
Ден Дайер

Я тільки запускав один приклад SecureRandom з MessageDigest і робив його шістнадцятковим кодом. Вся операція в моєму ПК з Windows 7 займала 33 мілісекунди. Це проблема. Я використовував SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); String randomNum = new Integer (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); результат = sha.digest (randomNum.getBytes ()); str = hexEncode (результат);
УВМ

24

Багато дистрибутивів Linux (в основному на Debian) налаштовують OpenJDK для використання /dev/randomдля ентропії.

/dev/random за визначенням повільний (і навіть може блокувати).

Звідси у вас є два варіанти розблокування:

  1. Поліпшити ентропію, або
  2. Зменшити вимоги до випадковості.

Варіант 1, Покращення ентропії

Для того, щоб отримати більше ентропії INTO /dev/random, спробуйте haveged демон. Це демон, який постійно збирає ентропію HAVEGE і працює також у віртуалізованому середовищі, оскільки для неї не потрібне спеціальне обладнання, лише сам процесор і годинник.

У Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

На RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Варіант 2. Зменшити вимоги до випадковості

Якщо з якихось причин рішення вище не допомагає або вам не байдуже криптографічно сильна випадковість, ви можете /dev/urandomзамість цього перейти , що гарантовано не блокується.

Щоб зробити це у всьому світі, відредагуйте файл jre/lib/security/java.securityу встановленій вами установці Java за замовчуванням для використання /dev/urandom(через іншу помилку, її потрібно вказати як /dev/./urandom).

Подобається це:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Тоді вам більше не доведеться вказувати це в командному рядку.


Примітка. Якщо ви робите криптографію, вам потрібна хороша ентропія. Справа в суті - випуск PRNG для Android знизив безпеку гаманців Bitcoin.


Визвали свою відповідь, але " /dev/randomза визначенням повільний (і навіть може блокувати)" неправильний; це повністю залежить від конфігурації системи. Більш нові машини можуть мати, наприклад, швидкий RNG в процесорі, який може використовуватися, а машини BSD, як правило, мають таку ж реалізацію для /dev/randomі /devl/urandom. Тим не менш, ти, мабуть, не повинен покладатися на /dev/random швидкість, обов'язково. У віртуальних машинах ви можете встановити набір клієнтських інструментів на VM клієнта, щоб можна було використовувати RNG хост-операційної системи.
Maarten Bodewes

17

У мене була подібна проблема з SecureRandomблокуванням дзвінків протягом приблизно 25 секунд на безголовому сервері Debian. Я встановив havegedдемона для того, щоб забезпечити /dev/randomйого поповнення, на безголових серверах вам потрібно щось подібне для створення необхідної ентропії. SecureRandomЗараз мої дзвінки можуть зайняти мілісекунд.


4
apt-get install hasged then update-rc.d haveged faged default
Rod Lima

11

Якщо ви хочете по-справжньому "криптографічно сильної" випадковості, тоді вам потрібно сильне джерело ентропії. /dev/randomповільно, оскільки йому доводиться чекати, коли системні події збирають ентропію (читання дисків, мережеві пакети, рух миші, натискання клавіш тощо).

Більш швидке рішення - апаратний генератор випадкових чисел. Можливо, у вас вже є одна вбудована материнська плата; ознайомтеся з документацією hw_random, щоб дізнатись, як з’ясувати, чи є у вас, і як ним користуватися. Пакет rng-tools включає в себе демон, який подаватиме ентропію, створену апаратним забезпеченням /dev/random.

Якщо HRNG недоступний у вашій системі, і ви готові пожертвувати силою ентропії для продуктивності, ви захочете отримати хороший PRNG з даними даних /dev/randomі дозволити PRNG виконати основну частину роботи. Існує кілька схвалених NIST PRNG , перелічених у SP800-90, які легко реалізувати.


Добре, але мій код є частиною комерційної програми. У мене немає контролю над середовищем сервера. Я думаю, що цільові сервери завжди без миші та клавіатури і повністю покладаються на дисковий та мережевий введення / виведення для ентропії, що, мабуть, є кореневою проблемою.
David G

3
Я виявив, що / dev / random залежає від системних подій, тому, як тимчасове вирішення проблеми, я просто переміщав мишу вперед і назад, поки мінявся тест ....
David K

Цей концентратор 82802 для чіпсету i820 був болісно повільним (RIP). Я вражений, що ви могли зібрати з нього все корисне. Я думаю, що я витратив більше часу на блокування, а не на збирання октетів.
jww

6

Використовуючи Java 8, я виявив, що в Linux виклик SecureRandom.getInstanceStrong()дасть мені NativePRNGBlockingалгоритм. Це часто блокується протягом багатьох секунд, щоб генерувати кілька байт солі.

Я перейшов на явне прохання NativePRNGNonBlockingзамість цього, і, як очікували від імені, він більше не блокувався. Я поняття не маю, які наслідки для цього мають безпека. Імовірно, що не блокує версія не може гарантувати кількість ентропії, що використовується.

Оновлення : Гаразд, я знайшов це чудове пояснення .

Коротше кажучи, щоб уникнути блокування, використовуйте new SecureRandom(). Це використовує /dev/urandom, що не блокує і в основному так само безпечно /dev/random. З поста: "Єдиний раз, коли ви хочете зателефонувати / dev / random - це коли машина вперше завантажується, а ентропія ще не накопичилася".

SecureRandom.getInstanceStrong() дає абсолютний найсильніший RNG, але його безпечно використовувати лише в ситуаціях, коли купа блокування не вплине на вас.


1
Я дозволяв би лише getInstanceStrong()довгострокові ключі, такі як сертифікати TLS. І навіть тоді я б скоріше використовував new SecureRandom()або сумісний з генератором пари клавіш, або генератор випадкових чисел Так, так, це дає відповідь, якщо /dev/urandom не блокується: врешті-решт все-таки покладається на ентропію системи; але загалом це дуже хороша порада . Якщо /dev/urandomблоки, можливо, доведеться виправити джерело проблеми, а не вашу програму Java.
Maarten Bodewes

5

Існує інструмент (принаймні на Ubuntu), який подасть штучну випадковість у вашу систему. Команда проста:

rngd -r /dev/urandom

і вам може знадобитися судо спереду. Якщо у вас немає пакету rng-tools, вам потрібно буде встановити його. Я спробував це, і це, безумовно, допомогло мені!

Джерело: matt vs world


2
Це дещо небезпечно, оскільки повністю відключає оцінку рівня ентропії ядра Linux у загальній системі. Я думаю, що для тестування (читається: Дженкінс працює з тестовим набором програми) за допомогою /dev/./urandom це добре, але у виробництві це не так.
mirabilos

Це насправді єдине рішення, яке працювало на мене. У мене була проблема "недостатньо ентропії", коли будували проект Android з Gradle на Jenkins CI, і передача параметра для збірки не допомогла.
Слав

Мені довелося поєднувати sudo rngd -r /dev/urandomз sudo apt install rng-toolsxenial
MrMesees

5

Я зіткнувся з тим же питанням . Після деяких гуглів з правильними пошуковими термінами я натрапив на цю приємну статтю про DigitalOcean .

hasged - це потенційне рішення без шкоди для безпеки.

Я лише цитую відповідну частину статті.

На основі принципу HAVEGE і раніше на основі пов'язаної з ним бібліотеки hasged дозволяє генерувати випадковість на основі варіацій у часі виконання коду на процесорі. Оскільки для одного фрагмента коду майже неможливо зайняти той самий точний час для виконання, навіть в одній і тій же середовищі на одному і тому ж апаратному забезпеченні, час запуску однієї або декількох програм повинен відповідати для виведення випадкового джерела. Тегелізована реалізація запускає випадкове джерело вашої системи (як правило, / dev / random), використовуючи відмінності у лічильнику часових штампів процесора (TSC) після повторного виконання циклу.

Як встановити hasged

Дотримуйтесь кроків у цій статті. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Я опублікував це тут


5

Проблема, на яку ви посилалися, /dev/randomполягає не в SecureRandomалгоритмі, а в джерелі випадковості, який він використовує. Два є ортогональними. Вам слід розібратися, яке з двох сповільнює вас.

Сторінка "Нечасті математики", яку ви пов’язали, явно зазначає, що вони не звертаються до джерела випадковості.

Ви можете спробувати різних постачальників JCE, таких як BouncyCastle, щоб побачити, чи SecureRandomшвидша їх реалізація .

Короткий пошук також виявляє патчі Linux, які замінюють реалізацію за замовчуванням на Fortuna. Я не знаю багато більше про це, але ви можете розслідувати.

Я також повинен зазначити, що хоча дуже небезпечно використовувати погано реалізований SecureRandomалгоритм та / або джерело випадковості, ви можете скочувати власного постачальника JCE за допомогою спеціальної реалізації SecureRandomSpi. Вам потрібно буде пройти процес із Sun, щоб підписати свого провайдера, але це насправді досить просто; їм просто потрібно, щоб ви надіслали їм факс форму, в якій зазначається, що ви знаєте обмеження експорту в криптобібліотеках США.


Ці різні постачальники JCE корисні лише тоді, коли вони використовують інше джерело ентропії, що в основному означає, що їм доведеться використовувати певний апарат, наприклад HSM. В іншому випадку вони настільки ж ймовірні, що можуть спостерігатися уповільнення, залежно від кількості ентропії, яку вони отримують із системи.
Maarten Bodewes

3

Використовувати захищений випадковий вибір як джерело ініціалізації для алгоритму, що повторюється; ви можете використовувати твістер Mersenne для об'ємної роботи замість того, що використовується в UncommonMath, який існує вже деякий час і зарекомендував себе краще, ніж інші прнг

http://en.wikipedia.org/wiki/Mersenne_twister

Переконайтесь, що оновлюйте час і час захищений випадковий випадок, що використовується для ініціалізації, наприклад, у вас може бути один захищений випадковий генерований на клієнта, використовуючи один генератор псевдовипадкових генераторів мерсена на клієнта, отримуючи достатньо високий ступінь рандомізації


2
Ця відповідь неправильна: твістер Мерсен не є захищеним генератором випадкових чисел. Це був би хороший алгоритм для Random, але не для SecureRandom.
Maarten Bodewes

3

Згідно з документацією , різні алгоритми, які використовуються SecureRandom, є в порядку уподобання:

  • У більшості * NIX систем
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBблокування
    4. NativePRNGNonBlocking
  • У системах Windows
    1. SHA1PRNG
    2. Windows-PRNG

Оскільки ви запитували про Linux, я ігнорую реалізацію Windows, а також SunPKCS11, який дійсно доступний лише в Solaris, якщо тільки ви не встановили його самостійно - і тоді ви б цього не запитували.

Згідно з тією ж документацією, якими є ці алгоритми

SHA1PRNG
Початковий посів насіння зараз проводиться за допомогою комбінації системних атрибутів та пристрою збирання ентропії java.security.

NativePRNG
nextBytes() використовує /dev/urandom
generateSeed()використання/dev/random

NativePRNGBЗаблокування
nextBytes() та generateSeed()використання/dev/random

NativePRNGNonBlocking
nextBytes() та generateSeed()використання/dev/urandom

Це означає, що якщо ви використовуєте SecureRandom random = new SecureRandom(), він знижує цей список, поки не знайде той, який працює, який, як правило, буде NativePRNG. А це означає, що воно виходить з себе /dev/random(або використовує це, якщо ви явно генеруєте насіння), а потім використовує /dev/urandomдля отримання наступних байтів, ints, double, booleans, what-have -s.

Оскільки /dev/randomвін блокує (він блокує, поки не буде достатньо ентропії в пулі ентропії), це може унеможливити виконання.

Одне рішення для цього - використовувати щось на кшталт hasged для створення достатньої кількості ентропії, інше - /dev/urandomзамість цього. Хоча ви можете встановити, що для всього jvm, кращим рішенням є це для цього конкретного примірника SecureRandom, використовуючи SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking"). Зауважте, що цей метод може кинути NoSuchAlgorithmException, якщо NativePRNGNonBlocking, тому будьте готові до відпадання до замовчування.

SecureRandom random;
try {
    random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
    random = new SecureRandom();
}

Також зауважте, що в інших системах * nix /dev/urandomможе поводитися по-різному .


Чи /dev/urandomдостатньо випадкових?

Звичайна мудрість вважає, що лише /dev/randomдосить випадкова. Однак деякі голоси відрізняються. У «Правильному способі використання SecureRandom» та «Міфи про / dev / urandom» стверджується, що /dev/urandom/це так само добре.

Користувачі, які перебувають на стеку інформаційної безпеки, згодні з цим . В основному, якщо вам доведеться запитати, /dev/urandomце добре для ваших цілей.


2

Я сам не стикався з цією проблемою, але я породив нитку при запуску програми, яка негайно намагається генерувати насіння, а потім гине. Метод, за допомогою якого ви викликаєте randoms, приєднається до цього потоку, якщо він живий, тому перший виклик блокується лише в тому випадку, якщо він відбувається дуже рано у виконанні програми.


Це досить екстремальний злом, але це може спрацювати; не сказано, що використаний PRNG може не використовувати додатковий насіннєвий матеріал, який все ще може призвести до блокування. Слід віддавати перевагу використанню іншого випадкового числа, що забезпечує або фіксує ентропію в системі. Як це може бути принаймні тимчасовим рішенням, я не все-таки проголосував відповідь.
Maarten Bodewes

2

Мій досвід був лише з повільною ініціалізацією PRNG, а не з генерацією випадкових даних після цього. Спробуйте більш нетерплячу стратегію ініціалізації. Оскільки їх дорого створити, поводьтеся з ним як з однотонним і повторно використовуйте той самий екземпляр. Якщо в одному екземплярі занадто багато дискусійних потоків, об'єднайте їх або зробіть їх локальними.

Не варто йти на компроміс з генерацією випадкових чисел. Слабкість там загрожує всій вашій безпеці.

Я не бачу багато генераторів на основі атомного розпаду COTS, але для них є кілька планів, якщо вам справді потрібно багато випадкових даних. Один із сайтів, на який завжди можна подивитися цікаві речі, включаючи HotBits, це Fourmilab Джона Уокера.


1
Я завжди цікавився цим питанням, оскільки продукти розпаду андронічного тау майже досягають ідеалу рандомізованого джерела, я просто не можу позбутися свого бажання використовувати це, а не алгоритмічні інструменти. З метою операції, я давно вирішив, що деякий передовий час є ендемічним для всіх захищених інструментів. Якщо комусь знадобиться рандомізер, якого можна викликати в конструкторі, і просто пам’ятайте, що він сконструюється під час завантаження сторінки, він закопується під avl своп і навіть настільки вибагливий, як і я, це залишається непоміченим.
Ніколас Джордан

Набори мікросхем Intel 8xx (і, мабуть, багато інших) мають апаратний RNG, який використовує тепловий шум, справді непередбачуваний квантовий ефект. Моделі надійної платформи можуть містити і апаратні RNG, але, на жаль, той, який є у мого ноутбука, не має.
erickson

Це залежить від конкретного РНГ, якщо він висіває один раз або якщо через деякий час засіває. NIST визначає PRNG, які перезавантажувались, але багато програмних реалізацій цього не роблять. Перебудова коду навколо сингтона - жахлива ідея, особливо щодо багатопотокових реалізацій; краще виправити джерело проблеми: повільне висівання через відсутність ентропії. Якщо ви використовуєте синглтон, використовуйте його для надання насіння для інших реалізацій SecureRandom, які повністю детерміновані. Такий дизайн, мабуть, вимагає певних знань.
Maarten Bodewes

@MaartenBodewes Це хороші моменти. Якщо реалізація така, що блокує, чекаючи ентропії системи, я вважаю, що трактувати це як сингл у вашій програмі не є жахливою ідеєю, оскільки джерело, що лежить в основі, є одинарним. Але використання цього одного екземпляра для посіву інших є гарною пропозицією, навіть якщо це складно. Я не впевнений, але я думаю, що постачальник Sun (а потім і Oracle) протягом SecureRandomостанніх 10 років змінився кілька разів за свою ентропію.
erickson

Я дуже впевнений, що це змінилося досить багато разів, настільки, що я не буду намагатися і вносити всі зміни в цей коментар :). Менш вірогідним є те, що уповільнення SecureRandomвсе ще залишається проблемою, але низька ентропія в системі завжди буде проблемою. Використання синглтона створить сильно зв'язаний код, який є дизайнерським анти-шаблоном. Тому його слід застосовувати з особливою обережністю; бажано, щоб ви вирішили проблему, потрібно змінити всі посилання в коді.
Maarten Bodewes

2

Це здається, що вам слід зрозуміти свої вимоги до RNG. Найсильнішою криптографічною вимогою RNG (наскільки я це зрозумів) було б те, що навіть якщо ви знаєте алгоритм, який використовується для їх генерування, і ви знаєте всі раніше генеровані випадкові числа, ви не зможете отримати корисну інформацію про будь-яке з випадкових чисел, згенерованих у майбутнє, не витрачаючи непрактичну кількість обчислювальної потужності.

Якщо вам не потрібна ця повна гарантія випадковості, то, ймовірно, є відповідні компроміси щодо продуктивності. Я схильний би погодитися з відповіддю Дена Дайєра про AESCounterRNG від Uncommons-Maths або Fortuna (одним з її авторів є Брюс Шнайер, експерт з криптографії). Я ніколи не використовував, але ідеї здаються авторитетними на перший погляд.

Я думаю, що якщо ви можете періодично генерувати початкове випадкове насіння (наприклад, один раз на день або годину чи будь-що інше), ви можете використовувати шифр швидкого потоку для отримання випадкових чисел з послідовних фрагментів потоку (якщо шифр потоку використовує XOR, то просто пройти в потоці нулів або забрати біти XOR безпосередньо). ECRYPT в eStreamПроект має багато хорошої інформації, включаючи показники ефективності. Це не підтримує ентропію між моментами, коли ви поповнюєте її, тому, якщо хтось знав одне з випадкових чисел та алгоритм, який ви використовували, технічно це можливо, з великою кількістю обчислювальної потужності, зламати шифр потоку та здогадатися про його внутрішній стан, щоб можна було передбачити майбутні випадкові числа. Але вам доведеться вирішити, чи достатньо цього ризику та його наслідків для виправдання витрат на підтримання ентропії.

Редагувати: ось деякі криптографічні нотатки про RNG, які я знайшов у мережі, які виглядають дуже актуальною для цієї теми.


1
"Фортуна (один з її авторів - Брюс Шнейер, фахівець з криптографії)", а другий - Нільс Фергюсон, фахівець з криптографії :-)
Стів Джессоп

2

Якщо ваше обладнання підтримує це, спробуйте скористатись утилітою Java RdRand, якою я є автор.

Він заснований на RDRANDінструкції Intel, і це приблизно в 10 разів швидше, ніж SecureRandomпропускна здатність та відсутність проблем для великих обсягів.


Зауважте, що ця реалізація працює лише на тих процесорах, які надають інструкцію (тобто коли встановлено rdrandпрапор процесора). Вам потрібно явно інстанціювати це через RdRandRandom()конструктор; конкретні Providerне реалізовані.


3
Ви можете прочитати people.umass.edu/gbecker/BeckerChes13.pdf і не забувати ніколи використовувати лише дані Intel RDRAND. Завжди змішуйте його з деякими іншими непередбачуваними даними, такими як вихід шифру потоку aRC4 (посіяний з / dev / urandom і з першими кількома кібайт викиду, викинутими за їх відомим зміщенням).
mirabilos

+1 мірабіло. Я думаю RDRAND, що це гарне джерело, але воно трохи недостовірне. Це, безумовно, має бути одним із вкладів багатьох у колекціонера (без образи на Девіда Джонстона).
jww

Я проголосував, виправив посилання та надав довідкову інформацію. Якщо ви не згодні, будь ласка, відкатіть правки.
Maarten Bodewes

1

Ще щось на що слід звернути увагу - це властивість securerandom.source у файлі lib / security / java.security

Можливо, вигода від продуктивності використання / dev / urandom, а не / dev / random. Пам'ятайте, що якщо якість випадкових чисел важлива, не робіть компромісу, який порушує безпеку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.