Generación de par de llaves RSA 2048: vía openssl 0.5s via gpg 30s, ¿por qué la diferencia?

Generación de pares de llaves RSA 2048: a través de openssl 0.5s a través de gpg 30s, por qué la diferencia Hay varios progtwigs que pueden gerar los pares de keys públicos / privados de RSA

GnuPG / OpenPGP por ejemplo tiene un wizzard siendo envidado a través de

 gpg --gen-key

OpenSSL puede generar un par de llaves usando estas líneas de command

 openssl genrsa -out testkey.private 2048
 openssl rsa -in testkey.private -pubout -out testkey.public

para la misma cosa, que está generando un par de keys RSA 2048 bit, puedo percibir -en la misma máquina- times muy diferentes.

openssl genera un par de llaves en aproximadamente 0.5s
gpg tarda unos 30 anuncios e incluso "mueve el mouse para generar aleatoriedad / entropía"

¿Se puede explicar la diferencia? Sé que gpg tiene algo más que solo la creación de la key RSA, sin embargo, elijo específicamente la opción (4)

 Seleccione el tipo de key que desea:
    (1) RSA y RSA (pnetworkingeterminado)
    (2) DSA y Elgamal
    (3) DSA (solo señal)
    (4) RSA (solo señal)
 ¿Tu seleccion?

Por lo tanto, realmente lo único que se genera es un par de llaves RSA de 2048 bits. Sin embargo, ¿la diferencia de time es de 30 segundos?

Para mí, parece que o bien gpg está perdiendo time innecesariamente o OpenSSL no está esperando el time suficiente y, por lo tanto, crea keys inseguras.

Mi pregunta es ¿qué podría explicar la diferencia?

Actualizar

La creación de RSA debe tomar como input algo de aleatoriedad. Por lo tanto, para asegurarnos de que el openssl rápido no es simplemente el resultado de usar un poco de aleatoriedad almacenada, lo ejecuto varias veces

 time bash -c "para i en {1..50}; do openssl genrsa -out / dev / null 2048; hecho;"

cuyos performances

 0m16.577s reales
 usuario 0m16.309s
 sys 0m0.092s

que es que para 50 2048 bits de keys RSA (supongo que necesitan mucha entropía / aleatoriedad) openssl todavía solo necesitaba 16 segundos. Mi suposition aquí sería, por lo tanto, la "respuesta" que openssl debe romperse. Después de todo, desconfío de que mi Linux (un kernel 3.2.0-59) se haya vuelto tan bueno en la generación de aleatoriedad.

Tal vez la diferencia es simplemente que openssl usa /dev/urandom y gpg usa /dev/random que de ser cierto podría explicar la diferencia de time, mi problema es que no sé cómo me enteraría de esto, para verificar esto.

actualización2

Para probar la fuente de randoms de openssl que utilicé

 strace -xe trace = file, leer, escribir, cerrar openssl genrsa -out testkey5.private 2048 2> & 1 |  grep random -A1

cuyos performances

 open ("/ dev / urandom", O_RDONLY | O_NOCTTY | O_NONBLOCK) = 4
 leer (4, "\ x21 \ xd8 \ xaa \ xf1 \ x2b \ x5f \ x4a \ x89 \ x5d \ x6c \ x58 \ x82 \ xc1 \ x88 \ x21 \ x04 \ xfa \ x5b \ x18 \ x98 \ x8a \ x34 \ x2b \ xe3 \ xf3 \ xc0 \ xb1 \ xef \ xfb \ x44 \ x15 \ x09 ", 32) = 32

así que parece que 32 bytes de /dev/urandom (no el "mejor" /dev/random ) es suficiente para el par de keys RSA de 2048bit en openssl. ¡Por lo tanto, es tan rápido!

Mediciones

La generación del par de llaves RSA de 2048bit significa

  • 32 bytes de solo /dev/urandom (usando openssl)
  • 300 bytes de dev/random (usando OpenPGP GNU Privacy Guard)

esto explica por supuesto la diferencia de time!

GnuPG consume varios bytes de /dev/random para cada byte aleatorio que realmente usa. Puede verificarlo fácilmente con este command:

 start cmd:> strace -e trace=open,read gpg --armor --gen-random 2 16 2>&1 | tail open("/etc/gcrypt/rngseed", O_RDONLY) = -1 ENOENT (No such file or directory) open("/dev/urandom", O_RDONLY) = 3 read(3, "\\\224F\33p\314j\235\7\200F9\306V\3108", 16) = 16 open("/dev/random", O_RDONLY) = 4 read(4, "/\311\342\377...265\213I"..., 300) = 128 read(4, "\325\3\2161+1...302@\202"..., 172) = 128 read(4, "\5[\372l\16?\...6iY\363z"..., 44) = 44 open("/home/hl/.gnupg/random_seed", O_WRONLY|O_CREAT, 0600) = 5 cCVg2XuvdjzYiV0RE1uzGQ== +++ exited with 0 +++ 

Para generar 16 bytes de entropía de alta calidad, GnuPG lee 300 bytes de /dev/random .

Esto se explica aquí: Arquitectura de subsistema de número aleatorio

Linux almacena un máximo de 4096 bytes (ver cat /proc/sys/kernel/random/poolsize ) de entropía. Si un process necesita más que el disponible (ver cat /proc/sys/kernel/random/entropy_avail ), entonces el uso de la CPU se vuelve más o less irrelevante a medida que la velocidad de alimentación del grupo de entropía del núcleo se convierte en el factor relevante.

Su sugerencia de que esta diferencia se debe a que openssl usa / dev / urandom y gpg usa /dev/random es correcta.

Puedes ver cómo baja la entropía disponible al generar keys con gpg usando:

 watch -n 1 cat /proc/sys/kernel/random/entropy_avail 

Usé un progtwig para generar la descripción de los pasos para configurar una tarjeta inteligente OpenGPG con gpg , así que tuve que ejecutar gpg varias veces hasta que todo salió como estaba previsto. Después de las ejecuciones iniciales noté que /dev/random no tendría suficiente entropía y gpg simplemente se detendría esperando que se acumulara nueva entropía.

Escribí un pequeño progtwig para proporcionar datos adicionales no aleatorios, y al hacerlo, gpg no se "detenía", sino que generaba las keys casi de inmediato: agradable para probar el script para que se ejecute correctamente, pero por supuesto no es algo que debería hacer al generar su llaves reales

El progtwig para acelerar gpg ( no usar en situaciones reales ):

 # For testing purposes only # DO NOT USE THIS, tHIS DOES NOT PROVIDE ENTROPY TO /dev/random 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) 

Cuando ejecuto esto mientras entropy_avail , puedo ver que la entropía disponible sube a más de 3800.