Quando inserisco la riga di comando openssl dhparam -text 1024
il sicuro-primo risultante è 1032 bit invece di 1024 bit. Sembra che il 1 ° byte sia sempre 0. Perché è questo?
Prova questo:
openssl genrsa | openssl rsa -text
Guarda ciascuno dei campi; i numeri primi, gli esponenti, tutti loro. Ora riprova, e ancora e ancora. Noterai qualche incongruenza sul fatto che sia presente un byte zero iniziale. A volte lo è, a volte non lo è. Il modello è questo: se il primo bit del primo byte "reale" è impostato - cioè, se il primo carattere esadecimale è minore di 8 - allora non ci sarà uno zero iniziale visualizzato (o memorizzato), ma se è 8 o superiore, verrà anteposto un byte zero.
Questo rende abbastanza chiaro che il problema che stanno risolvendo è l'interpretazione dei segni. Con valori firmati, il primo bit è il segno del numero; l'aggiunta di uno zero iniziale rimuove qualsiasi ambiguità.
Per vedere cosa è effettivamente memorizzato (non visualizzato) guarda questo:
openssl genrsa | openssl asn1parse
Vedrai che mentre sono visualizzati solo 64 o 32 byte, vedrai l= 33
o l= 65
che indica che un byte extra è effettivamente memorizzato. Questo è il tuo zero byte iniziale che hai visto prima.
Come per i tasti DH a 32-bit, guarda questo:
$ openssl dhparam 32 -text
Generating DH parameters, 32 bit long safe prime, generator 2
This is going to take a long time
PKCS#3 DH Parameters: (32 bit)
prime: 2714658203 (0xa1ce659b)
generator: 2 (0x2)
Quindi, sembra solo 4 byte anche se il bit iniziale è impostato. Ma diamo un'occhiata a asn1parse:
0:d=0 hl=2 l= 10 cons: SEQUENCE
2:d=1 hl=2 l= 5 prim: INTEGER :A1CE659B
9:d=1 hl=2 l= 1 prim: INTEGER :02
Quindi per questo primo a 32 bit, vengono memorizzati 5 byte anche se sono stati visualizzati solo 4 byte.
Il motivo per cui non hai vedere il byte zero questa volta è che, poiché il valore memorizzato è solo a 32 bit, può essere visualizzato come un semplice numero intero senza segno e pertanto la libreria di visualizzazione di OpenSSL mostra il valore decimale e il valore esadecimale in paren invece di mostrarti solo una stringa di byte esadecimali separati da due punti. Ma lo zero iniziale è ancora lì, come abbiamo visto nell'uscita asn1.
veramente ottieni un primo di 1024 bit: un primo di 1024 bit è un intero il cui valore è maggiore di 2 1023 ma inferiore a 2 1024 . Questo è ciò che OpenSSL ti restituisce. Tuttavia, quando si tratta di memorizzare tale intero in un file, è necessario utilizzare alcune convenzioni di codifica per trasformare tale intero in byte. OpenSSL utilizza ASN.1 con DER ( Distincished Encoding Rules ).
In ASN.1, il tipo è INTEGER
, ovvero un valore intero generico potenzialmente negativo. Le regole DER indicano che INTEGER
codificherà come tag ( 02
, il tag standard per INTEGER
) quindi una lunghezza ( 81 81
, che significa "129": il valore sarà una sequenza di 129 byte) , quindi il valore stesso, con interpretazione firmata big-endian . La parola importante qui è "firmata": poiché un INTEGER
potrebbe essere negativo, ma il tuo primo è positivo, la sua codifica deve iniziare con un bit di valore 0. Se il primo è stato codificato su esattamente 128 byte, il primo bit del primo byte sarebbe un 1 e il INTEGER
sarebbe considerato negativo. Quindi, viene aggiunto un byte extra 00
(come per le regole DER, la codifica deve avere una lunghezza minima a condizione che il primo bit corrisponda al segno atteso, quindi può essere aggiunto solo un singolo byte 00
). La lunghezza totale, con l'intestazione, è di 132 byte. Il numero intero matematico che è così codificato è ancora un numero primo a 1024 bit, non un intero 1032-bit o 1056-bit.
Se viene impostato il bit più alto nel valore di 1024 bit, viene anteposto un byte 0 perché senza il quale il numero verrebbe interpretato come un numero negativo.
Leggi altre domande sui tag encryption openssl