Génération de paires de clés RSA 2048: via openssl 0.5s via gpg 30s, pourquoi la différence?

9

Génération de paires de clés RSA 2048: via openssl 0.5s via gpg 30s, pourquoi la différence Il existe plusieurs programmes qui peuvent calculer les paires de clés publiques / privées RSA

GnuPG / OpenPGP, par exemple, a un sorcier envié via

gpg --gen-key

OpenSSL peut générer une paire de clés à l'aide de ces lignes de commande

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

pour la même chose, qui génère une paire de clés RSA 2048 bits, je peux percevoir - sur la même machine - des temps très différents.

opensslgénère une paire de clés en environ 0,5 s
gpgprend environ 30 et même des publicités "déplacez la souris pour générer l'aléatoire / l'entropie"

Peut-on expliquer la différence? Je sais que gpg fait un peu plus que la création de clés RSA, mais je choisis spécifiquement l'option (4)

Veuillez sélectionner le type de clé que vous souhaitez:
   (1) RSA et RSA (par défaut)
   (2) DSA et Elgamal
   (3) DSA (signe uniquement)
   (4) RSA (signe uniquement)
Votre sélection?

Par conséquent, la seule chose générée est une paire de clés RSA à 2048 bits. Pourtant, le décalage horaire est de 30 secondes?

Pour moi, il semble que soit gpg perd du temps inutilement, soit OpenSSL n'attend pas assez de temps et crée donc des clés non sécurisées.

Ma question est ce qui pourrait expliquer la différence?

Mise à jour

La création RSA doit prendre en entrée un certain caractère aléatoire. Par conséquent, pour m'assurer que l'opensl rapide n'est pas simplement le résultat de l'utilisation de quelques aléas stockés, je les exécute par lots plusieurs fois

time bash -c "for i in {1..50}; do openssl genrsa -out / dev / null 2048; done;"

qui donne

réel 0m16.577s
utilisateur 0m16.309s
sys 0m0.092s

c'est-à-dire que pour 50 clés RSA 2048bits (je suppose qu'il faut beaucoup d'entropie / aléatoire), openssl n'a encore eu besoin que de 16 secondes. Mon hypothèse ici serait donc la "réponse" qui doit être ouverte à openssl. Après tout, je me méfie de mon Linux (un noyau 3.2.0-59) qui est devenu si génial pour générer de l'aléatoire.

Peut-être que la différence est simplement que les utilisations openssl /dev/urandomet les utilisations gpg /dev/randomqui, si elles sont vraies, pourraient expliquer la différence de temps, mon problème est que je ne sais pas comment je saurais à ce sujet, pour le vérifier.

update2

Pour tester la source aléatoire d'OpenSL, j'ai utilisé

strace -xe trace = fichier, lecture, écriture, fermeture openssl genrsa -out testkey5.private 2048 2> & 1 | grep random -A1

qui donne

open ("/ dev / urandom", O_RDONLY | O_NOCTTY | O_NONBLOCK) = 4
lire (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

il semble donc que 32 octets de /dev/urandom(pas le "meilleur" /dev/random) suffisent pour la paire de clés RSA à 2048 bits dans openssl. C'est donc tellement rapide!

Des mesures

Génération de paires de clés RSA 2048 bits

  • 32 octets de seulement /dev/urandom(en utilisant openssl)
  • 300 octets de /dev/random(en utilisant openPGP GNU Privacy Guard)

cela explique bien sûr le décalage horaire!

humanANDpeace
la source

Réponses:

10

GnuPG consomme plusieurs octets /dev/randompour chaque octet aléatoire qu'il utilise réellement. Vous pouvez facilement vérifier cela avec cette commande:

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 +++

Afin de produire 16 octets d'entropie de haute qualité, GnuPG lit 300 octets /dev/random.

Ceci est expliqué ici: Architecture du sous-système à nombre aléatoire

Linux stocke un maximum de 4096 octets (voir cat /proc/sys/kernel/random/poolsize) d'entropie. Si un processus a besoin de plus que ce qui est disponible (voir cat /proc/sys/kernel/random/entropy_avail), l'utilisation du processeur devient alors plus ou moins non pertinente, car la vitesse d'alimentation du pool d'entropie du noyau devient le facteur pertinent.

Hauke ​​Laging
la source
Impressionnant. Merci pour la perspicacité. Je pense que cela éclaire à peu près la question! Il semble donc que openssl soit satisfait de 32 octets de /dev/urandomgpg de moins bonne qualité et dit même "1 octet /dev/randomn'est pas suffisant pour 1 octet de hasard". Cela ne signifierait-il pas que les clés openssl sont plus sujettes à "trop ​​peu d'aléatoire" par rapport aux gpg?
humanityANDpeace
1
@humanityANDpeace Randomness est une discussion sans fin. Il n'y a pas longtemps, l '"utilisateur principal" de ce site a affirmé qu'il /dev/urandométait suffisamment bon pour la cryptographie. Sur la liste de diffusion GnuPG, il se moquerait probablement de cela. AFAIK il est impossible de prouver que certaines données sont purement aléatoires. Vous pouvez trouver le caractère non aléatoire, mais uniquement là où vous recherchez exactement ce modèle.
Hauke ​​Laging
oui je vois :) Le fait que gpg utilise 300 octets /dev/randomalors qu'optsl n'utilise que 32 octets /dev/urandomsemble suggérer un risque de sécurité potentiel pour l'utilisateur prudent qui souhaite une paire de clés RSA 2048 bits. J'opterais donc pour gpg. 32bytes semble peu awefully
humanityANDpeace
2
@HaukeLaging «L'utilisateur principal» de ce site a obtenu ce conseil de «l'utilisateur principal» de la sécurité de l' information et de la cryptographie , avec une explication qui a du sens (contrairement au calcul de la taille du pool d'entropie de Linux, qui ne le fait pas). Un rand de / dev / urandom est-il sécurisé pour une clé de connexion? "La reponse courte est oui. La réponse longue est également oui. "
Gilles 'SO- arrête d'être méchant'
2
La lecture de 32 octets à partir d'un CSPRNG bien semé donne 256 bits de sécurité (ce qui est sacrément beaucoup ). Une clé RSA-2048 bits n'offre qu'environ 112 bits de sécurité. La seule propriété douteuse de a /dev/urandomest que (sur linux) il ne bloque pas avant d'être initialisé directement après le démarrage. Une fois semé, il restera en sécurité pour toujours.
CodesInChaos
7

Votre suggestion selon laquelle cette différence s'explique par le fait que openssluses / dev / urandom et gpguses /dev/randomest correcte.

Vous pouvez regarder l'entropie disponible descendre tout en générant des clés en gpgutilisant:

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

J'ai utilisé un programme pour générer la description des étapes de configuration d'une carte à puce OpenGPGgpg , j'ai donc dû exécuter gpgplusieurs fois jusqu'à ce que tout fonctionne comme prévu. Après les essais initiaux, j'ai remarqué qu'il /dev/randomn'y aurait pas assez d'entropie et que gpg s'arrêterait juste en attendant que la nouvelle entropie s'accumule.

J'ai écrit un petit programme pour fournir des données supplémentaires non aléatoires et, ce faisant gpg, ne "s'arrêtait" pas mais générait les clés presque immédiatement: agréable pour tester le script pour qu'il s'exécute correctement, mais bien sûr ce n'est pas quelque chose que vous devriez faire lors de la génération de votre réel clés.

Le programme pour accélérer gpg( ne pas utiliser en situation réelle ):

# 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)

Lorsque je lance cela en regardant, entropy_availje peux voir l'entropie disponible monter à plus de 3800.

Anthon
la source
Merci d'avoir répondu. J'ai toujours hâte de tester gpg, qui malheureusement est moins batchable et plus interactif. .. Encore. Êtes-vous sûr que l'appel de répétition caten lui-même ne drainera pas déjà l'entropie? Avez-vous des preuves ou une source qui indiquent les utilisations de gpg /dev/randomqui perfectionneraient la réponse? Enfin, cela signifie-t-il également que openssl génère des paires de clés RSA de moindre qualité que gqg?
humanityANDpeace
@humanityANDpeace Il est possible (quoique moins évident) d'utiliser GnuPG en mode batch. Recherchez Unattended key generationdans le fichier /usr/share/doc/packages/gpg2/DETAILS(ou quoi que ce soit dans votre distribution). La /dev/randompreuve est dans ma réponse.
Hauke ​​Laging du
La réponse de @humanityANDpeace Hauke ​​est plus à propos, mais j'y ai trouvé plusieurs références en recherchant comment configurer ma carte OpenGPG. Le traitement par lots n'est pas anodin, mais le programme python que j'ai utilisé est disponible sur bitbucket
Anthon
J'aime les deux réponses et les deux suggèrent la bonne solution. merci pour le lien bitbucket!
humanityANDpeace
1
L'apparition d'un nouveau processus consomme de l'entropie, donc une meilleure approche serait d'utiliser le readshell intégré:while read -r < /proc/sys/kernel/random/entropy_avail; do clear; date; printf '\nAvailable entropy: %s bytes\n' "$REPLY"; sleep 1; done
nyuszika7h