Чи безпечна нитка SecureRandom?


103

Чи SecureRandomбезпечна нитка? Тобто після ініціалізації його може бути покладено доступ до наступного випадкового числа, щоб бути безпечним для потоків? Вивчення вихідного коду, схоже, показує, що воно є, і цей звіт про помилку, схоже, вказує на те, що його відсутність документації як безпечного потоку є проблемою javadoc. Хтось підтвердив, що це насправді безпечно для ниток?

Відповіді:


108

Так. Він поширюється Random, який завжди мав фактичну реалізацію безпечної нитки, і, з Java 7, явно гарантує безпеку потоків.

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


3
Дякуємо за оновлення. Як не дивно, помилка позначена закритою, оскільки "не виправиться". Але вони все одно це виправили. Ну добре, я не заздрю ​​їм розміру своєї бази помилок.
Yishai

4
ініціалізація a SecureRandomможе бути не лише повільною, але й може зависати через відсутність ентропії
Walter Tross

8
Будь ласка, майте на увазі, що ThreadLocalRandom дуже легко зламати, тому якщо ви плануєте виставляти створене значення світові, використовуйте SecureRandom замість jazzy.id.au/default/2010/09/20/…
walv

2
Я збираюся тут вийти на кінцівку і сказати, що ця відповідь невірна. Договір на Random, який гарантує безпеку потоку, не є обов'язковим для підкласів. Звичайно, всі інші властивості Random задокументовані не є обов'язковими для підкласів, тому я не розумію, чому слід припускати безпеку потоків.
президент Джеймс К. Полк

2
@JamesKPolk Незбереження властивості супертипу порушить принцип замінюваності.
Еріксон

11

Поточна реалізація безпеки SecureRandomє безпечною для потоків, зокрема двох мутуючих методів nextBytes(bytes[])та setSeed(byte[])синхронізована.

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

Найкраще рішення спочатку синхронізувати в SecureRandomекземплярі вручну . Це означає, що кожен стек викликів придбає два блокування на одному об’єкті, але це зазвичай дуже дешево на сучасних JVM. Тобто в явній синхронізації себе немає великої шкоди. Наприклад:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }

3
Принаймні, у JDK 10, SecureRandom базується на постачальнику послуг і перевіряє, чи постачальник безпечний для потоків, лише синхронізуючи, якщо його немає, у nextBytes.
нафг

java.security.SecureRandom#nextBytesв Java 8 не синхронізовано. Скажіть, будь ласка, у якій версії Java ви знайшли синхронізовану #nextBytes?
Хайме Хаблуцель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.