Generazione di keypair RSA 2048: tramite openssl 0,5s tramite gpg 30s, perché la differenza?


9

Generazione di keypair RSA 2048: tramite openssl 0,5s tramite gpg 30s, perché la differenza Esistono diversi programmi che possono gerarchizzare i keypair pubblici / privati ​​RSA

GnuPG / OpenPGP, ad esempio, ha un wizzard invocato tramite

gpg --gen-key

OpenSSL può generare una coppia di chiavi usando queste righe di comando

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

per la stessa cosa, che sta generando una coppia di chiavi RSA 2048 bit che riesco a percepire - sulla stessa macchina - tempi molto diversi.

opensslgenera una coppia di chiavi in ​​circa 0,5 secondi
gpgrichiede circa 30 e persino annunci "sposta il mouse per generare casualità / entropia"

La differenza può essere spiegata? So che gpg fa un po 'di più della semplice creazione della chiave RSA, tuttavia scelgo specificamente l'opzione (4)

Seleziona il tipo di chiave che desideri:
   (1) RSA e RSA (impostazione predefinita)
   (2) DSA ed Elgamal
   (3) DSA (solo segno)
   (4) RSA (solo segno)
La tua selezione?

Quindi davvero l'unica cosa generata è una coppia di chiavi RSA a 2048 bit. Eppure la differenza di tempo sta crollando a 30 secondi?

A me sembra che o gpg stia sprecando inutilmente tempo o OpenSSL non stia aspettando abbastanza tempo e quindi crea chiavi insicure.

La mia domanda è: cosa potrebbe spiegare la differenza?

Aggiornare

La creazione di RSA deve prendere come input un po 'di casualità. Quindi per essere sicuro che il rapido openssl non sia semplicemente il risultato dell'uso di una casualità memorizzata, l'ho eseguito in batch più volte

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

che cede

0m16.577 reali
utente 0m16.309s
sys 0m0.092s

il che è che per 50 chiavi RSA a 2048 bit (presumo occorra molta entropia / casualità) si apre ancora solo 16 secondi. La mia ipotesi qui sarebbe quindi la "risposta" che openssl deve essere rotta. Dopotutto sono diffidente sul fatto che il mio Linux (un kernel 3.2.0-59) sia diventato così eccezionale nel generare casualità.

Forse la differenza è semplicemente che openssl usa /dev/urandome gpg usa /dev/randomche se vero potesse spiegare la differenza di tempo il mio problema è che non so come lo scoprirò, per verificarlo.

Update2

Per testare la fonte di random di openssl ho usato

strace -xe trace = file, leggi, scrivi, chiudi openssl genrsa -out testkey5.private 2048 2> & 1 | grep random -A1

che cede

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

quindi sembra che 32 byte da /dev/urandom(non il "migliore" /dev/random) siano sufficienti per la coppia di chiavi RSA a 2048 bit in openssl. Quindi è così veloce!

misure

Mezzi di generazione della coppia di chiavi RSA a 2048 bit

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

questo spiega ovviamente la differenza di tempo!

Risposte:


10

GnuPG consuma diversi byte /dev/randomper ogni byte casuale che utilizza effettivamente. Puoi facilmente verificarlo con questo 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 +++

Per generare 16 byte di entropia di alta qualità, GnuPG legge 300 byte da /dev/random.

Questo è spiegato qui: Architettura del sottosistema di numeri casuali

Linux memorizza un massimo di 4096 byte (vedi cat /proc/sys/kernel/random/poolsize) di entropia. Se un processo ha bisogno di più di quello disponibile (vedi cat /proc/sys/kernel/random/entropy_avail), l'utilizzo della CPU diventa più o meno irrilevante in quanto la velocità di alimentazione del pool di entropia del kernel diventa il fattore rilevante.


Degno di nota. Grazie per la comprensione. Penso che si illumini praticamente per quanto riguarda la domanda! Quindi sembra che mentre openssl sia soddisfatto di 32 byte di /dev/urandomgpg di qualità inferiore dice anche "1 byte /dev/randomnon è abbastanza buono per 1 byte di casuale". Ciò non significherebbe che le chiavi di openssl sono più inclini a "troppa casualità" rispetto a quelle di gpg?
umanità e

1
@humanityANDpeace La casualità è una discussione senza fine. Non molto tempo fa l '"utente principale" di questo sito ha affermato che /dev/urandomera abbastanza buono per scopi crittografici. Sulla mailing list di GnuPG probabilmente sarebbe stato deriso per quello. AFAIK è impossibile dimostrare che alcuni dati sono puramente casuali. Puoi trovare la non casualità ma solo dove cerchi esattamente quel modello.
Hauke ​​Laging,

sì, vedo :) Il fatto che gpg usi 300byte di /dev/randommentre openssl usa solo 32bytes /dev/urandomsembra suggerire un potenziale rischio per la sicurezza per l'utente cauto come vuole una coppia di chiavi RSA a 2048 bit. Vorrei quindi optare per gpg. 32byte sembrano incredibilmente piccoli
umanità e la

2
@HaukeLaging L '"utente principale" di questo sito ha ricevuto questo consiglio dall' "utente principale" di Sicurezza delle informazioni e crittografia , con una spiegazione che ha senso (diversamente dal calcolo delle dimensioni del pool di entropia di Linux, che non lo fa). Un rand di / dev / urandom è sicuro per una chiave di accesso? “La risposta breve è sì. Anche la lunga risposta è sì. "
Gilles 'SO-smetti di essere malvagio' il

2
32 byte letti da un CSPRNG ben seminato offrono 256 bit di sicurezza (il che è un vero affare ). Una chiave RSA-2048 bit offre solo circa 112 bit di sicurezza. L'unica proprietà dubbia di a /dev/urandomè che (su Linux) non si blocca prima che venga seminato direttamente dopo l'avvio. Una volta che è stato seminato rimarrà sicuro per sempre.
Codici InCos

7

Il tuo suggerimento che questa differenza è perché opensslutilizza / dev / urandom e gpgusi /dev/randomè corretto.

Puoi osservare l'entropia disponibile che scende mentre si generano le chiavi gpgusando:

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

Ho usato un programma per generare la descrizione dei passaggi per configurare una smart card OpenGPGgpg , quindi ho dovuto eseguire gpgpiù volte fino a quando tutto ha funzionato come previsto. Dopo le prove iniziali ho notato che /dev/randomnon ci sarebbe stata abbastanza entropia e gpg si sarebbe semplicemente bloccato in attesa dell'accumulo di nuova entropia.

Ho scritto un piccolo programma per fornire dati extra non casuali, e quando lo facevo gpgnon "si fermava" ma generava le chiavi quasi immediatamente: bello per testare lo script per funzionare correttamente, ma ovviamente non è qualcosa che dovresti fare mentre generi il tuo vero chiavi.

Il programma per accelerare gpg( non utilizzare in situazioni reali ):

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

Quando eseguo questo mentre guardo entropy_availposso vedere l'entropia disponibile salire a oltre 3800.


Grazie per la risposta. Non vedo ancora l'ora di provare gpg, che purtroppo è meno collegabile e più interattivo. .. Ancora. Sei sicuro che il richiamo ripetuto di catper sé non prosciughi già l'entropia? Hai qualche prova o fonte che dice /dev/randomche usi gpg che perfezionerebbero la risposta? Infine, ciò significa anche che openssl genera coppie di chiavi RSA di qualità inferiore rispetto a gqg?
umanità e

@humanityANDpeace È possibile (sebbene meno ovvio) usare GnuPG in modalità batch. Cerca Unattended key generationnel file /usr/share/doc/packages/gpg2/DETAILS(o qualunque cosa possa essere nella tua distribuzione). Le /dev/randomprove sono nella mia risposta.
Hauke ​​Laging,

@humanityANDpeace La risposta di Hauke ​​è più precisa, ma ho trovato diversi riferimenti ad essa mentre cercavo come configurare la mia carta OpenGPG. Il batch non è banale, ma il programma Python che ho usato l'ho reso disponibile su bitbucket
Anthon

Mi piacciono entrambe le risposte ed entrambi i tipi di suggerire la soluzione giusta. grazie per il link bitbucket!
umanità e

1
La generazione di un nuovo processo consuma entropia, quindi un approccio migliore sarebbe l'uso della readshell incorporata:while read -r < /proc/sys/kernel/random/entropy_avail; do clear; date; printf '\nAvailable entropy: %s bytes\n' "$REPLY"; sleep 1; done
nyuszika7h
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.