¿Cómo lidiar con un generador lento de SecureRandom?

165

Si quieres un número aleatorio criptográficamente fuerte en Java, lo usas SecureRandom. Lamentablemente, SecureRandompuede ser muy lento. Si se usa /dev/randomen Linux, puede bloquear la espera de que se acumule suficiente entropía. ¿Cómo se evita la penalización de rendimiento?

¿Alguien ha usado Matemáticas poco comunes como solución a este problema?

¿Alguien puede confirmar que este problema de rendimiento se ha resuelto en JDK 6?

David G
fuente
Parece que esto está relacionado con la lentitud SecureRandom.generateSeed () . Hay un defecto rechazado que explica la lentitud y una solución alternativa: JDK-6521844: SecureRandom se cuelga en sistemas Linux
AlikElzin-kilaka
Echa un vistazo a / dev / urandom (no / dev / random). Considera simplemente obtener un generador de números aleatorios desde urandom si hay un problema de bloqueo.
jcalfee314
Relacionado con Windows: stackoverflow.com/questions/49322948/…
patrikbeno

Respuestas:

79

Si desea datos aleatorios verdaderos, desafortunadamente debe esperarlos. Esto incluye la semilla para un SecureRandomPRNG. Uncommon Maths no puede recopilar datos aleatorios verdaderos más rápido que SecureRandom, aunque puede conectarse a Internet para descargar datos semilla de un sitio web en particular. Supongo que es poco probable que sea más rápido de lo /dev/randomque está disponible.

Si quieres un PRNG, haz algo como esto:

SecureRandom.getInstance("SHA1PRNG");

Las cadenas que se admiten dependen del SecureRandomproveedor de SPI, pero puede enumerarlas con Security.getProviders()y Provider.getService().

Sun es aficionado a SHA1PRNG, por lo que está ampliamente disponible. No es especialmente rápido a medida que avanzan los PRNG, pero los PRNG solo serán números crujientes, no bloqueando la medición física de la entropía.

La excepción es que si no llama setSeed()antes de obtener datos, el PRNG se iniciará una vez la primera vez que llame next()o nextBytes(). Por lo general, hará esto utilizando una cantidad bastante pequeña de datos aleatorios verdaderos del sistema. Esta llamada puede bloquear, pero hará que su fuente de números aleatorios sea mucho más segura que cualquier variante de "hash la hora actual junto con el PID, agregue 27 y espere lo mejor". Sin embargo, si todo lo que necesita son números aleatorios para un juego, o si desea que la transmisión sea repetible en el futuro usando la misma semilla para fines de prueba, una semilla insegura sigue siendo útil.

Steve Jessop
fuente
Uncommons Maths solo descarga datos de Internet para sembrar, no devuelve esos datos aleatorios cuando genera números aleatorios.
Dan Dyer
Lo mismo con SecureRandom: / dev / urandom es solo para la inicialización.
AviD
Sí. Cuando el interrogador dice "si quieres un número aleatorio, usas SecureRandom, esto puede ser lento", pensé que tal vez está usando getSeed para todo y drenando su grupo de entropía. La solución no es obtener JDK 6, es usar SecureRandom de la forma prevista;
Steve Jessop
@Dan Dyer: he corregido mi comentario sobre Uncommon Maths. Eché un vistazo a su página, así que sabía que por "números aleatorios" me refería a "por su origen" en lugar de "volver al usuario". Pero tiene usted razón de que no es lo que he dicho ...
Steve Jessop
"Está ampliamente disponible". ¿No se incluye con cada JDK compatible? Está en la lista de nombres estándar de seguridad de Java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Sean Reilly
176

Debería poder seleccionar el más rápido pero un poco menos seguro / dev / urandom en Linux usando:

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

Sin embargo, esto no funciona con Java 5 y versiones posteriores ( Java Bug 6202721 ). La solución sugerida es usar:

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

(tenga en cuenta el extra /./)

Thomas Leonard
fuente
24
Tenga en cuenta que el informe de error de Java dice "No es un defecto". En otras palabras, aunque el valor predeterminado es /dev/urandom, Sun trata esto como una cadena mágica y lo utiliza de /dev/randomtodos modos, por lo que debe simularlo. ¿Cuándo una file:URL no es una file:URL? Cada vez que Sun decide que no es así :-(
Jim Garrison
66
Después de pasar mucho tiempo investigando esto, parece que la configuración normal, incluso con file:/dev/urandomset in -Djava.security.egdo in securerandom.sourceen el archivo java.security, /dev/random/todavía se lee cada vez SecureRandom.getSeed()(o setSeed()se llama). La solución alternativa con file:/dev/./urandomresultados en no leer /dev/randomnada (confirmado con strace)
mate b
77
/dev/urandomno es menos seguro que /dev/randomcuando se implementa con un CSPRNG moderno: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo
Creo que el principal temor /dev/urandom/es qué sucede si lo usas para generar secretos en el nuevo hardware fuera de la caja, que podría estar en un estado bastante predecible. /dev/urandom/no bloqueará la entropía a pesar de que ese es un caso en el que deberías. La situación es aún peor si el secreto es persistente, como si lo primero que hace su dispositivo en el primer arranque es generar un par de claves pública-privada. Fuera de esas situaciones de miedo, un bien /dev/urandomes mejor que usar los SecureRandomalgoritmos comunes de todos modos.
Steve Jessop
1
¿Cuál es el correcto? -Djava.security.egd = archivo: / dev /./ urandom o archivo: /// dev / urandom @mattb
Aarish Ramesh
35

En Linux, la implementación predeterminada para SecureRandomes NativePRNG(código fuente aquí ), que tiende a ser muy lenta. En Windows, el valor predeterminado es SHA1PRNG, que como otros señalaron, también puede usar en Linux si lo especifica explícitamente.

NativePRNGdifiere de AESCounterRNG deSHA1PRNG Uncommons Maths en que recibe continuamente entropía del sistema operativo (al leer de ). Los otros PRNG no adquieren ninguna entropía adicional después de la siembra./dev/urandom

AESCounterRNG es aproximadamente 10 veces más rápido que SHA1PRNG, IIRC es en sí mismo dos o tres veces más rápido que NativePRNG.

Si necesita un PRNG más rápido que adquiera entropía después de la inicialización, vea si puede encontrar una implementación Java de Fortuna . El PRNG central de una implementación de Fortuna es idéntico al utilizado por AESCounterRNG, pero también hay un sofisticado sistema de agrupación de entropía y reposición automática.

Dan Dyer
fuente
Este enlace no funciona. uncommons-maths.dev.java.net/nonav/api/org/uncommons/maths/… . ¿Hay algún lugar donde pueda ver esto?
UVM
@Unni Acaba de actualizar el enlace. Tenga en cuenta que las afirmaciones de rendimiento que hice en esta respuesta podrían no ser válidas. Creo que las cosas pueden haber mejorado en las versiones recientes de Java y puede haber diferencias en el rendimiento entre plataformas (es decir, Windows frente a Liux).
Dan Dyer
Estaba ejecutando un ejemplo de SecureRandom con un MessageDigest e hice un código hexadecimal. Toda la operación en mi PC con Windows 7 tomó 33 milisegundos. Es un problema. Utilicé SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); String randomNum = new Integer (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); result = sha.digest (randomNum.getBytes ()); str = hexEncode (resultado);
UVM
24

Muchas distribuciones de Linux (en su mayoría basadas en Debian) configuran OpenJDK para usar /dev/randomen entropía.

/dev/random es, por definición, lento (e incluso puede bloquear).

Desde aquí tienes dos opciones sobre cómo desbloquearlo:

  1. Mejorar la entropía, o
  2. Reducir los requisitos de aleatoriedad.

Opción 1, mejorar la entropía

Para obtener más entropía /dev/random, prueba el demonio adosado . Es un demonio que recolecta continuamente entropía HAVEGE, y funciona también en un entorno virtualizado porque no requiere ningún hardware especial, solo la CPU y un reloj.

En Ubuntu / Debian:

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

En RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Opción 2. Reducir los requisitos de aleatoriedad

Si por alguna razón la solución anterior no ayuda o no le importa la aleatoriedad criptográficamente fuerte, puede cambiar a /dev/urandom, lo que garantiza que no se bloqueará.

Para hacerlo globalmente, edite el archivo jre/lib/security/java.securityen su instalación Java predeterminada para usar /dev/urandom(debido a otro error , debe especificarse como /dev/./urandom).

Me gusta esto:

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

Entonces nunca tendrá que especificarlo en la línea de comando.


Nota: Si haces criptografía, necesitas una buena entropía. Caso en cuestión: el problema de Android PRNG redujo la seguridad de las billeteras de Bitcoin.

rustyx
fuente
Votó su respuesta, pero " /dev/randompor definición es lento (e incluso puede bloquear)" está mal; depende completamente de la configuración del sistema. Las máquinas más nuevas pueden tener, por ejemplo, un RNG rápido en la CPU que puede usarse, y las máquinas BSD generalmente tienen la misma implementación para /dev/randomy /devl/urandom. Aún así, probablemente no deberías confiar en /dev/random ser rápido, necesariamente. En las máquinas virtuales, es posible que desee instalar el conjunto de herramientas del cliente en la máquina virtual del cliente para poder utilizar el RNG del sistema operativo host.
Maarten Bodewes
17

Tuve un problema similar con las llamadas al SecureRandombloqueo durante aproximadamente 25 segundos a la vez en un servidor Debian sin cabeza. Instalé el havegeddaemon para asegurarme de que /dev/randomesté lleno, en servidores sin cabeza necesitas algo como esto para generar la entropía requerida. Mis llamadas a SecureRandomahora tal vez tarden milisegundos.

trueno
fuente
44
apt-get install haveged luego update-rc.d valores predeterminados hasged
Rod Lima
11

Si quieres una aleatoriedad verdaderamente "criptográficamente fuerte", entonces necesitas una fuente de entropía fuerte. /dev/randomes lento porque tiene que esperar a que los eventos del sistema recopilen entropía (lecturas de disco, paquetes de red, movimiento del mouse, pulsaciones de teclas, etc.).

Una solución más rápida es un generador de números aleatorios de hardware. Es posible que ya tenga una integrada en su placa base; Consulte la documentación de hw_random para obtener instrucciones sobre cómo averiguar si la tiene y cómo usarla. El paquete rng-tools incluye un demonio que alimentará la entropía generada por hardware /dev/random.

Si un HRNG no está disponible en su sistema, y ​​está dispuesto a sacrificar la fuerza de la entropía por el rendimiento, querrá sembrar un buen PRNG con datos de /dev/random, y dejar que el PRNG haga la mayor parte del trabajo. Hay varios PRNG aprobados por el NIST enumerados en SP800-90 que son fáciles de implementar.

Chris Kite
fuente
Buen punto, pero mi código es parte de una aplicación comercial. No tengo ningún control sobre el entorno del servidor. Creo que los servidores de destino siempre carecen de mouse y teclado y dependen completamente de E / S de disco y red para la entropía, que probablemente sea el problema raíz.
David G
3
Descubrí que / dev / random dependía de los eventos del sistema, así que, como solución temporal, simplemente moví el mouse de un lado a otro mientras se ejecutaba mi prueba ...
David K
Ese concentrador 82802 para el chipset i820 fue extremadamente lento (RIP). Me sorprende que pudieras reunir algo útil de él. Creo que pasé más tiempo bloqueándolo en lugar de recolectar octetos.
jww
6

Usando Java 8, descubrí que en Linux las llamadas SecureRandom.getInstanceStrong()me darían el NativePRNGBlockingalgoritmo. Esto a menudo bloqueará durante muchos segundos para generar unos pocos bytes de sal.

Cambié a pedirlo explícitamente NativePRNGNonBlocking, y como se esperaba del nombre, ya no se bloqueó. No tengo idea de cuáles son las implicaciones de seguridad de esto. Presumiblemente, la versión sin bloqueo no puede garantizar la cantidad de entropía que se utiliza.

Actualización : Ok, encontré esta excelente explicación .

En pocas palabras, para evitar el bloqueo, use new SecureRandom(). Esto utiliza /dev/urandom, que no bloquea y es básicamente tan seguro como /dev/random. De la publicación: "La única vez que desea llamar / dev / random es cuando la máquina se inicia por primera vez y la entropía aún no se ha acumulado".

SecureRandom.getInstanceStrong() te proporciona el RNG más fuerte, pero solo es seguro de usar en situaciones en las que un montón de bloqueos no te afectará.

Lachlan
fuente
1
Solo permitiría getInstanceStrong() claves a largo plazo, como las de los certificados TLS. E incluso entonces preferiría usar new SecureRandom()un generador de pares de claves o un generador de números aleatorios que cumplan con FIPS. Entonces, sí, esto proporciona una respuesta, si /dev/urandom no se bloquea: al final, aún depende de la entropía del sistema; pero es muy buen consejo en general . Si /dev/urandombloquea, es posible que deba solucionar el origen del problema en lugar de su aplicación Java.
Maarten Bodewes
5

Hay una herramienta (al menos en Ubuntu) que alimentará la aleatoriedad artificial en su sistema. El comando es simplemente:

rngd -r /dev/urandom

y es posible que necesites un sudo en la parte delantera. Si no tiene el paquete rng-tools, deberá instalarlo. Intenté esto, ¡y definitivamente me ayudó!

Fuente: matt vs world

David K
fuente
2
Esto es algo peligroso porque deshabilita completamente la estimación del nivel de entropía del kernel de Linux, en todo el sistema. Creo que para propósitos de prueba (lee: Jenkins ejecutando el testuite de una aplicación) usando /dev/./urandom está bien, pero en producción, no lo está.
mirabilos
Esta es realmente la única solución que funcionó para mí. Tuve un problema de "no suficiente entropía" al crear un proyecto de Android con Gradle en Jenkins CI, y pasar un parámetro a la compilación no ayudó.
Eslavo
Tuve que combinar sudo rngd -r /dev/urandomcon sudo apt install rng-toolsxenial
MrMesees
5

Me enfrenté al mismo problema . Después de buscar en Google con los términos de búsqueda correctos, me encontré con este bonito artículo sobre DigitalOcean .

haveged es una solución potencial sin comprometer la seguridad.

Simplemente estoy citando la parte relevante del artículo aquí.

Basado en el principio HAVEGE, y previamente basado en su biblioteca asociada, hasged permite generar aleatoriedad basada en variaciones en el tiempo de ejecución del código en un procesador. Dado que es casi imposible que una sola pieza de código tome el mismo tiempo exacto de ejecución, incluso en el mismo entorno en el mismo hardware, el momento de ejecutar uno o varios programas debería ser adecuado para sembrar una fuente aleatoria. La implementación fragmentada genera la fuente aleatoria de su sistema (generalmente / dev / random) usando diferencias en el contador de sello de tiempo (TSC) de su procesador después de ejecutar un ciclo repetidamente

Cómo instalar haveged

Sigue los pasos de este artículo. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Lo he publicado aquí.

tipo tan al azar
fuente
5

El problema al que hizo referencia /dev/randomno es con el SecureRandomalgoritmo, sino con la fuente de aleatoriedad que utiliza. Los dos son ortogonales. Debes descubrir cuál de los dos te está frenando.

La página de Matemáticas poco común que ha vinculado explícitamente menciona que no abordan la fuente de aleatoriedad.

Puede probar diferentes proveedores de JCE, como BouncyCastle, para ver si su implementación SecureRandomes más rápida.

Una breve búsqueda también revela parches de Linux que reemplazan la implementación predeterminada con Fortuna. No sé mucho más sobre esto, pero puedes investigar.

También debo mencionar que, si bien es muy peligroso utilizar un SecureRandomalgoritmo mal implementado y / o una fuente de aleatoriedad, puede implementar su propio proveedor JCE con una implementación personalizada de SecureRandomSpi. Deberá pasar por un proceso con Sun para obtener la firma de su proveedor, pero en realidad es bastante sencillo; solo necesitan que les envíe por fax un formulario que indique que conoce las restricciones de exportación de EE. UU. a las bibliotecas de cifrado.

ykaganovich
fuente
Esos diferentes proveedores de JCE solo son útiles si usan otra fuente de entropía, lo que básicamente significa que tienen que usar una pieza específica de hardware, como un HSM. De lo contrario, es probable que experimenten ralentizaciones, dependiendo de la cantidad de entropía que extraigan del sistema.
Maarten Bodewes
3

Utilice el aleatorio seguro como fuente de inicialización para un algoritmo recurrente; podría usar un tornado Mersenne para el trabajo a granel en lugar del UncommonMath, que ha existido durante un tiempo y ha demostrado ser mejor que otro prng

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

Asegúrese de actualizar de vez en cuando el aleatorio seguro utilizado para la inicialización, por ejemplo, podría tener un aleatorio seguro generado por cliente, utilizando un generador pseudoaleatorio mersenne twister por cliente, obteniendo un grado suficientemente alto de aleatorización

Lorenzo Boccaccia
fuente
2
Esta respuesta es incorrecta: el tornado Mersenne no es un generador seguro de números aleatorios. Sería un buen algoritmo para Random, pero no para SecureRandom.
Maarten Bodewes
3

Según la documentación , los diferentes algoritmos utilizados por SecureRandom son, en orden de preferencia:

  • En la mayoría de los sistemas * NIX
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBlocking
    4. NativePRNGNonBlocking
  • En sistemas Windows
    1. SHA1PRNG
    2. Windows-PRNG

Dado que usted preguntó acerca de Linux, estoy ignorando la implementación de Windows, y también SunPKCS11, que solo está realmente disponible en Solaris, a menos que lo haya instalado usted mismo, y entonces no lo estaría preguntando.

Según esa misma documentación, lo que usan estos algoritmos son

SHA1PRNG
La inicialización inicial se realiza actualmente mediante una combinación de atributos del sistema y el dispositivo de recolección de entropía java.security.

NativePRNG
nextBytes() utiliza /dev/urandom
generateSeed()usos/dev/random

NativePRNGBbloqueo
nextBytes() y generateSeed()uso/dev/random

NativePRNGNonBlocking
nextBytes() y generateSeed()uso/dev/urandom

Eso significa que si lo usa SecureRandom random = new SecureRandom(), baja esa lista hasta que encuentre uno que funcione, que generalmente será NativePRNG. Y eso significa que se siembra desde /dev/random(o usa eso si explícitamente genera una semilla), luego lo usa /dev/urandompara obtener los siguientes bytes, ints, double, booleans, what-have-yous.

Dado que /dev/randomestá bloqueando (bloquea hasta que tiene suficiente entropía en el grupo de entropía), eso puede impedir el rendimiento.

Una solución para eso es usar algo como forjado para generar suficiente entropía, otra solución está usando en su /dev/urandomlugar. Si bien puede configurarlo para todo el jvm, una mejor solución es hacerlo para esta instancia específica de SecureRandom, mediante el uso SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking"). Tenga en cuenta que ese método puede generar una NoSuchAlgorithmException si NativePRNGNonBlocking, así que prepárese para recurrir al valor predeterminado.

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

También tenga en cuenta que en otros sistemas * nix, /dev/urandompuede comportarse de manera diferente .


¿Es lo /dev/urandomsuficientemente aleatorio?

La sabiduría convencional dice que solo /dev/randomes lo suficientemente aleatorio. Sin embargo, algunas voces difieren. En "La forma correcta de usar SecureRandom" y "Mitos sobre / dev / urandom" , se argumenta que /dev/urandom/es igual de bueno.

Los usuarios de la pila de seguridad de la información están de acuerdo con eso . Básicamente, si tiene que preguntar, /dev/urandomestá bien para su propósito.

SQB
fuente
2

No me he enfrentado a este problema, pero engendré un hilo al inicio del programa que inmediatamente intenta generar una semilla, luego muere. El método al que llamas randoms se unirá a ese hilo si está activo, por lo que la primera llamada solo se bloquea si ocurre muy temprano en la ejecución del programa.

Mella
fuente
Es un truco bastante extremo, pero podría funcionar; no se dice que el PRNG usado no pueda usar material de semilla adicional que aún podría conducir al bloqueo. Se debe preferir utilizar un número aleatorio diferente que proporcione o repare la entropía en el sistema. Como al menos puede proporcionar una solución temporal, he votado la respuesta.
Maarten Bodewes
2

Mi experiencia ha sido solo con una lenta inicialización del PRNG, no con la generación de datos aleatorios después de eso. Pruebe una estrategia de inicialización más entusiasta. Como son caros de crear, trátelo como un singleton y reutilice la misma instancia. Si hay demasiada contención de hilos para una instancia, agrúpelos o conviértalos en hilos locales.

No comprometa la generación de números aleatorios. Una debilidad allí compromete toda su seguridad.

No veo muchos generadores basados ​​en la desintegración atómica COTS, pero hay varios planes para ellos, si realmente necesita una gran cantidad de datos aleatorios. Un sitio que siempre tiene cosas interesantes para ver, incluidos HotBits, es el Fourmilab de John Walker.

erickson
fuente
1
Siempre me he preguntado sobre esto, ya que los productos de decaimiento de tau hadrónico casi alcanzan el ideal de una fuente aleatoria, simplemente no puedo deshacerme de mi deseo de usar eso en lugar de herramientas algorítmicas. Para el propósito de op, hace mucho tiempo decidí que un tiempo de front-end es endémico para todas las herramientas seguras. Si uno va a necesitar un aleatorizador, que se puede llamar en el constructor y solo recuerde construir uno en el momento de la carga de la página, está enterrado bajo el intercambio avl e incluso tan exigente como soy, no se nota.
Nicholas Jordan el
Los chipsets Intel 8xx (y probablemente muchos otros) tienen un RNG de hardware que utiliza ruido térmico, un efecto cuántico verdaderamente impredecible. Los módulos de plataforma de confianza también pueden contener RNG de hardware, pero desafortunadamente, el que está en mi computadora portátil no.
erickson el
Depende del RNG específico si se siembra una vez o si se vuelve a sembrar después de un tiempo. NIST especifica los PRNG que se reinician, pero muchas implementaciones de software no. Reestructurar el código alrededor de un singleton es una idea horrible, especialmente en implementaciones multiproceso; es mejor solucionar el origen del problema: la siembra lenta debido a la falta de entropía. Si usa un singleton, úselo para proporcionar semillas para otras implementaciones de SecureRandom que sean completamente deterministas. Sin embargo, este tipo de diseño probablemente requiere bastante conocimiento.
Maarten Bodewes
@MaartenBodewes Esos son buenos puntos. Si la implementación es una que bloquea, esperando la entropía del sistema, creo que tratarla como un singleton en su aplicación no es una idea horrible ya que la fuente subyacente es efectivamente un singleton. Pero usar esa instancia para sembrar otras es una buena sugerencia, incluso si es compleja. No estoy seguro, pero creo que el proveedor de Sun (y luego Oracle) SecureRandomha cambiado un par de veces en los últimos 10 años en su reunión de entropía.
erickson
Estoy muy seguro de que ha cambiado varias veces, tanto que no intentaré poner todos los cambios en este comentario :). Es menos probable que una lentitud SecureRandomsiga siendo un problema, pero una baja entropía en un sistema siempre será un problema. El uso de un singleton creará un código fuertemente acoplado, que es un antipatrón de diseño. Por lo tanto, debe usarse con extremo cuidado; preferiblemente tendría que revertir todas las referencias en el código para solucionar el problema.
Maarten Bodewes
2

Parece que debería ser más claro acerca de sus requisitos de RNG. El requisito de RNG criptográfico más fuerte (según tengo entendido) sería que, incluso si conoce el algoritmo utilizado para generarlos y conoce todos los números aleatorios generados previamente, no podría obtener ninguna información útil sobre ninguno de los números aleatorios generados en el futuro, sin gastar una cantidad poco práctica de potencia informática.

Si no necesita esta garantía completa de aleatoriedad, probablemente existan compensaciones de rendimiento apropiadas. Tendería a estar de acuerdo con la respuesta de Dan Dyer sobre AESCounterRNG de Uncommons-Maths o Fortuna (uno de sus autores es Bruce Schneier, un experto en criptografía). Nunca he usado tampoco, pero las ideas parecen ser respetables a primera vista.

Me gustaría pensar que si se pudiera generar una semilla aleatoria inicial periódicamente (por ejemplo, una vez al día o una hora o lo que sea), se puede utilizar un cifrado de flujo rápido para generar números aleatorios a partir de trozos sucesivos de la corriente (si el cifrado de flujo utiliza XOR a continuación, sólo pase una secuencia de nulos o tome los bits XOR directamente). EStream de ECRYPTEl proyecto tiene mucha buena información, incluyendo puntos de referencia de rendimiento. Esto no mantendría la entropía entre los puntos en el tiempo en que la repone, por lo que si alguien conociera uno de los números aleatorios y el algoritmo que utilizó, técnicamente podría ser posible, con mucha potencia informática, romper el cifrado de flujo y adivina su estado interno para poder predecir números aleatorios futuros. Pero tendría que decidir si ese riesgo y sus consecuencias son suficientes para justificar el costo de mantener la entropía.

Editar: aquí hay algunas notas del curso criptográfico sobre RNG que encontré en la red que parecen muy relevantes para este tema.

Jason S
fuente
1
"Fortuna (uno de sus autores es Bruce Schneier, un experto en criptografía)" - y el otro es Niels Ferguson, un experto en criptografía :-)
Steve Jessop
2

Si su hardware lo admite, intente utilizar Java RdRand Utility, de la cual soy el autor.

Se basa en las RDRANDinstrucciones de Intel y es aproximadamente 10 veces más rápido que SecureRandomy sin problemas de ancho de banda para la implementación de gran volumen.


Tenga en cuenta que esta implementación solo funciona en aquellas CPU que proporcionan la instrucción (es decir, cuando se establece el rdrandindicador del procesador). Necesita crear una instancia explícita a través del RdRandRandom()constructor; No Providerse ha implementado ningún específico .

usuario2781824
fuente
3
Es posible que desee leer people.umass.edu/gbecker/BeckerChes13.pdf y asegúrese de nunca usar solo datos de Intel RDRAND. Siempre mézclelo con otros datos impredecibles, como la salida de un cifrado de flujo aRC4 (sembrado de / dev / urandom y con los primeros KiB de salida desechados por su sesgo conocido).
mirabilos
+1 mirabilos. Creo que RDRANDes una buena fuente, pero es un poco poco confiable. Definitivamente debe ser una entrada de muchos en un coleccionista (sin ofender a David Johnston).
jww
He votado, arreglé el enlace y proporcioné información de fondo. Si no está de acuerdo, retroceda la edición.
Maarten Bodewes
1

Otra cosa a tener en cuenta es la propiedad securerandom.source en el archivo lib / security / java.security

Puede haber un beneficio de rendimiento al usar / dev / urandom en lugar de / dev / random. Recuerde que si la calidad de los números aleatorios es importante, no haga un compromiso que rompa la seguridad.

Diastrofismo
fuente