¿Por qué escribir en / dev / random no hace que la lectura paralela de / dev / random sea más rápida?

22

Por lo general, la lectura de /dev/randomproduce 100-500 bytes y bloques, esperando que se recopile una entropía.

¿Por qué la escritura de información /dev/randompor otros procesos no acelera la lectura? ¿No debería proporcionar la entropía requerida?

Puede ser útil para desbloquear gpgo software similar sin reiniciarlo y volver a ingresarlo todo, para generar claves no súper secretas, etc.

Vi.
fuente
3
Acabo de leer de su /dev/urandomlugar. /dev/urandomes tan seguro como /dev/randompara el uso criptográfico , el comportamiento de /dev/randomes un mal diseño.
Gilles 'SO- deja de ser malvado'
1
¿Cómo cambiar gpg --gen-keyde /dev/randoma /dev/urandomsin reiniciar?
Vi.
IIRC gpgha /dev/randomcodificado. Puede cambiar su configuración de udev para hacer /dev/randomel mismo dispositivo que /dev/urandom, entre otras posibilidades.
Gilles 'SO- deja de ser malvado'
@Gilles, todavía requiere reiniciar gpg --gen-key, por lo tanto, volver a ingresar los datos que solicita de forma interactiva (o usar métodos más inteligentes como especificar más parámetros de línea de comandos). También se perderá el tiempo de CPU que genera el cebado (gpg puede funcionar un minuto, imprime algunos +es y luego solicita datos aleatorios adicionales). Y da la sensación de "volvamos e iremos por otra ruta" en lugar de "tomemos un martillo y lo obliguemos a avanzar" ...
Vi.

Respuestas:

19

Puede escribir /dev/randomporque es parte de la forma de proporcionar bytes aleatorios adicionales /dev/random, pero no es suficiente, también debe notificar al sistema que hay entropía adicional a través de una ioctl()llamada.

Necesitaba la misma funcionalidad para probar mi programa de configuración de tarjeta inteligente , ya que no quería esperar a que mi mouse / teclado generara lo suficiente para las varias llamadas gpgque se hicieron para cada ejecución de prueba. Lo que hice fue ejecutar el programa Python, que sigue, en paralelo a mis pruebas. Por supuesto, no debe usarse en absoluto para la gpggeneración de claves reales , ya que la cadena aleatoria no es aleatoria en absoluto (la información aleatoria generada por el sistema seguirá intercalada). Si tiene una fuente externa para establecer la cadena random, entonces debería poder tener una entropía alta. Puede verificar la entropía con:

cat /proc/sys/kernel/random/entropy_avail

El programa:

#!/usr/bin/env python
# For testing purposes only 
# DO NOT USE THIS, THIS DOES NOT PROVIDE ENTROPY TO /dev/random, JUST BYTES

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
    time.sleep(0.001)

(No olvides matar el programa una vez que hayas terminado).

Anthon
fuente
1
Una solución mucho más simple sería su uso rngd. Está disponible como paquete en la mayoría de las distribuciones (¿todas?).
Patrick
44
random = "3420348024823049823-984230942049832423l4j2l42j"ver xkcd.com/221
user253751
@Patrick Probé al menos 3 posibles soluciones para agregar aleatoriedad, IIRC rngd fue una de ellas. Pero no funcionarían de inmediato (podría ser la configuración de Ubuntu 12.04 en ese momento), y para mí esta solución, con 10 líneas de código, era más simple.
Anthon
@Anthon: como nota al margen, no parecía xs4all.nl desde que mitnik lo usó para almacenar algunas cosas, hace décadas ... :)
woliveirajr
@woliveirajr, tuve mi cuenta de hacktic.nl transferida allí en algún lugar en 1992, he estado allí un tiempo, aunque no he vivido en los Países Bajos durante más de 20 años.
Anthon
14

Por lo general, está diseñado por desarrolladores de kernel y documentado en man 4 random:

Writing to /dev/random or /dev/urandom will update the entropy pool
with the data written, but this will not result in a higher entropy
count.  This means that it will impact the contents read from both
files, but it will not make reads from /dev/random faster.
Cuonglm
fuente
1

Anthony ya explicó que escribir a /dev/randomno aumenta el recuento de entropía y mostró cómo el ioctl RNDADDENTROPY (ver al azar (4) ) puede usarse para acreditar la entropía. Obviamente no es realmente seguro, así que aquí hay una alternativa cuando hay disponible un generador de números aleatorios de hardware.

Las siguientes implementaciones toman 512 bytes (4096 bits) de aleatoriedad /dev/hwrngy lo envían al grupo de entropía (acreditar 4 bits de entropía por byte, esta es una elección arbitraria de mi parte). Después de eso, invocará la llamada al sistema select (2) para bloquear cuando el grupo de entropía esté lleno (documentado en la página de manual al azar (4) ).

Una versión de Python:

import fcntl, select, struct
with open('/dev/hwrng', 'rb') as hw, open('/dev/random') as rnd:
    while True:
        d = hw.read(512)
        fcntl.ioctl(rnd, 0x40085203, struct.pack('ii', 4 * len(d), len(d)) + d)
        select.select([], [rnd], [])

Dado que la iso de Arch Linux no tenía Python instalado, aquí también hay una versión de Perl:

open my $hw, "</dev/hwrng" and open my $rnd, "</dev/random" or die;
for (;;) {
    my $l = read $hw, my $d, 512;
    ioctl $rnd, 0x40085203, pack("ii", 4 * $l, $l) . $d or die;
    vec(my $w, fileno $rnd, 1) = 1;
    select undef, $w, undef, undef
}

Esto es probablemente lo que hace el programa rngd (parte de rng-tools ) (sin verificar), excepto que usa herramientas (Python o Perl) que ya están comúnmente disponibles.

Lekensteyn
fuente
Si no tiene un generador de números aleatorios de hardware, puede usarlo en /dev/urandomlugar de hacerlo /dev/hwrngsi no le importan los valores aleatorios inseguros .
Lekensteyn
Hmm, descubrí que los dispositivos hwrng generan automáticamente entropía cuando es necesario, no se necesitan rngd o script adicionales. Sin embargo, hay un error cuando la getrandom()llamada al sistema se usa con hwrng en núcleos anteriores a 4.8-rc1 que produce un comportamiento de bloqueo. Una solución alternativa es hacer read()dos veces desde /dev/random, ver github.com/Lekensteyn/archdir/commit/…
Lekensteyn