Generación de pares de claves RSA 2048: a través de openssl 0.5s a través de gpg 30s, ¿por qué la diferencia?

9

Generación de pares de claves RSA 2048: a través de openssl 0.5s a través de gpg 30s, por qué la diferencia Hay varios programas que pueden generar pares de claves públicos / privados de RSA

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

gpg --gen-key

OpenSSL puede generar un par de claves usando estas líneas de comando

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

por lo mismo, eso es generar un par de claves RSA 2048 bit que puedo percibir, en la misma máquina, tiempos muy diferentes.

opensslgenera un par de claves en aproximadamente 0.5s,
gpgtoma aproximadamente 30 e incluso los anuncios "mueven el mouse para generar aleatoriedad / entropía"

¿Se puede explicar la diferencia? Sé que gpg hace algo más que la creación de la clave RSA, pero elijo específicamente la opción (4)

Seleccione qué tipo de clave desea:
   (1) RSA y RSA (predeterminado)
   (2) DSA y Elgamal
   (3) DSA (solo signo)
   (4) RSA (solo señal)
¿Tu seleccion?

Por lo tanto, realmente lo único generado es un par de claves RSA de 2048 bits. ¿Sin embargo, la diferencia horaria es de 30 segundos?

Para mí, parece que o gpg está perdiendo tiempo innecesariamente o OpenSSL no está esperando suficiente tiempo y, por lo tanto, crea claves inseguras.

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

Actualizar

La creación de RSA debe tomar como entrada algo de aleatoriedad. Por lo tanto, para asegurarme de que el openssl rápido no es simplemente el resultado de usar una aleatoriedad almacenada, la ejecuté varias veces

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

cuyos rendimientos

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

que es que para 50 claves de 2048 bits RSA (supongo que se necesita mucha entropía / aleatoriedad), openssl todavía solo necesitó 16 segundos. Por lo tanto, mi suposición aquí sería 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 generar aleatoriedad.

Tal vez la diferencia es simplemente que los usos de openssl /dev/urandomy gpg /dev/randomque, de ser cierto, podrían explicar la diferencia horaria, mi problema es que no sé cómo averiguaría esto, para verificarlo.

actualización2

Para probar la fuente del azar de openssl utilicé

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

cuyos rendimientos

abierto ("/ 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

entonces parece que 32 bytes de /dev/urandom(no el "mejor" /dev/random) es suficiente para el par de claves RSA de 2048 bits en openssl. ¡Por eso es tan rápido!

Mediciones

La generación de pares de claves RSA de 2048 bits significa

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

¡Esto explica, por supuesto, la diferencia horaria!

humanidad y paz
fuente

Respuestas:

10

GnuPG consume varios bytes de /dev/randomcada byte aleatorio que realmente usa. Puede verificarlo fácilmente con este comando:

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 /dev/random.

Esto se explica aquí: Arquitectura de subsistema de números aleatorios

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

Hauke ​​Laging
fuente
Impresionante. Gracias por la visión de usted. ¡Creo que se ilumina bastante con respecto a la pregunta! Entonces parece que mientras openssl está satisfecho con 32 bytes de /dev/urandomgpg de menor calidad, incluso dice "1 byte /dev/randomno es lo suficientemente bueno para 1 byte de aleatorio". ¿No significa esto que las claves openssl son más propensas a "muy poca aleatoriedad" en comparación con las GPG?
humanityANDpeace
1
@humanityANDpeace Randomness es una discusión interminable. No hace mucho, el "usuario maestro" de este sitio hizo la afirmación de que /dev/urandomera lo suficientemente bueno para fines de cifrado. En la lista de correo de GnuPG probablemente se reiría de eso por eso. AFAIK es imposible demostrar que ciertos datos son puramente aleatorios. Puede encontrar no aleatoriedad, pero solo donde busca exactamente ese patrón.
Hauke ​​Laging
sí, ya veo :) Aún así, el hecho de que gpg usa 300bytes de /dev/randommientras openssl usa solo 32bytes de /dev/urandomparece sugerir un riesgo de seguridad potencial para el usuario cauteloso que quiere un par de claves RSA de 2048 bits. Por lo tanto, optaría por gpg. 32bytes parece poco awefully
humanityANDpeace
2
@HaukeLaging El "usuario maestro" de este sitio recibió este consejo del "usuario maestro" de Seguridad de la Información y Criptografía , con una explicación que tiene sentido (a diferencia del cálculo del tamaño del grupo de entropía de Linux, que no lo hace). ¿Es seguro un rand de / dev / urandom para una clave de inicio de sesión? "La respuesta corta es sí. La respuesta larga también es sí ".
Gilles 'SO- deja de ser malvado'
2
La lectura de 32 bytes de un CSPRNG bien sembrado brinda 256 bits de seguridad (que es muchísimo ). Una clave de bit RSA-2048 solo ofrece aproximadamente 112 bits de seguridad. La única propiedad dudosa de a /dev/urandomes que (en Linux) no se bloquea antes de ser sembrada directamente después del arranque. Una vez que se haya sembrado, permanecerá seguro para siempre.
CodesInChaos
7

Su sugerencia de que esta diferencia se debe a que opensslutiliza / dev / urandom y gpgutiliza /dev/randomes correcta.

Puede ver la entropía disponible que baja mientras genera claves con el gpguso de:

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

Utilicé un programa para generar la descripción de los pasos para configurar una tarjeta inteligente OpenGPGgpg , por lo que tuve que ejecutar gpgvarias veces hasta que todo funcionó según lo previsto. Después de las ejecuciones iniciales, noté que /dev/randomno tendría suficiente entropía y gpg simplemente se detendría esperando que se acumule una nueva entropía.

Escribí un pequeño programa para proporcionar datos adicionales no aleatorios, y al hacerlo gpgno se "detendría" sino que generaría las claves casi de inmediato: es bueno probar que el script se ejecuta correctamente, pero por supuesto no es algo que debas hacer al generar tu verdadero llaves.

El programa 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_availveo, puedo ver que la entropía disponible sube a más de 3800.

Anthon
fuente
Gracias por la respuesta. Todavía estoy ansioso por probar gpg, que desafortunadamente es menos batchable y más interactivo. .. Todavía. ¿Estás seguro de que la llamada repetida de catpor sí misma no drena la entropía? ¿Tiene alguna evidencia o fuente que indique los usos de gpg /dev/randomque perfeccionarían la respuesta? Por último, ¿eso también significa que openssl genera pares de claves RSA de menor calidad que gqg?
humanityANDpeace
@humanityANDpeace Es posible (aunque menos obvio) usar GnuPG en modo por lotes. Busque Unattended key generationen el archivo /usr/share/doc/packages/gpg2/DETAILS(o lo que sea que esté en su distribución). La /dev/randomevidencia está en mi respuesta.
Hauke ​​Laging
La respuesta de @humanityANDpeace Hauke ​​es más precisa, pero encontré varias referencias al respecto mientras investigaba cómo configurar mi tarjeta OpenGPG. El procesamiento por lotes no es trivial, pero el programa de Python que he usado lo he puesto a disposición en bitbucket
Anthon
Me gustan ambas respuestas y ambas sugieren la solución correcta. gracias por el enlace bitbucket!
humanityANDpeace
1
Engendrar un nuevo proceso consume entropía, por lo tanto, un mejor enfoque sería utilizar el readshell incorporado:while read -r < /proc/sys/kernel/random/entropy_avail; do clear; date; printf '\nAvailable entropy: %s bytes\n' "$REPLY"; sleep 1; done
nyuszika7h