Se cambio un personaggio in un PEM privato, il PEM pubblico dovrebbe essere diverso?

2

Sto generando una chiave pubblica in formato PEM da una chiave privata in formato PEM. Ho notato che se cambio qualche carattere vicino alla fine del PEM privato, il PEM pubblico generato dal PEM privato modificato è esattamente lo stesso del risultato del PEM privato non modificato.

Ad esempio, questo PEM privato

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCAAZXj8YAEQya8jF8l6Hy56BcRBgplxPd8ZM5LIAWm0w1k/CgB
gvrI28W+5orOyqST2gC4EBEGmLw9s3NC8McL3qqFIQvd6SpWzCJEiI9n+wCkJLYf
715t6BwZo8F82AdqRHwL1lL0T4JeakgcFO5zno2l/NYKpZtS78vIq2F8pwIDAQAB
AoGAIAdFh+lPTMG4mYjN7eBEBQgrbVkDlP85pWhbrbRvdZRtT41APVCWi1diHSf2
J1PQ5iWv9F4gxHPG9fFGr8MrKk+jCM0/rDJsN7yC1yiSerS9zNvoSWu4D1cizRn2
ZOFi+TJZVHAoVvuh1vJdsFLkDmfoXelR6v6ojQxp6IftblECQQD7W4F92yHVIkRt
ZEz5TMYxtFF2d5uwi6XA/1MDuWpK0dK20a7DUGmgQ8faNfSZ/Dr1JmLx0OK/+Ocg
5HnzNo5NAkEAgl7Wa/Lr0TUH5h4L3SsJ1aeYUC6CbzJHBpNTvhuC7YEcs0AJL2k3
qYSM8VpU7q9iGHvfQhnKH9eBXlQbJBt4wwJBAJ1Pj6Ns2afCYoD0HRiJbCD/cVxr
Tw0W2Q4IvbO+/z8EQpQYdv/V+8VJpnJzAjq9GUkEVThyOvdal4yGcaw9oKECQC8V
/a+jXxSCaMXuGC7bOoQWMebTxXxP1mNDlr1UxmbteOYsvKSJBfeNzjHlhENoyK87
HhmLovr5JNpi2iKiYW0CQDyniRLXCyBVayJd3QkuMFKVNUuOytXUFWNXTpLA1Nbb
2K+leKb2KSyyEmRFC2X+QwF9ZBP1C3b0lgBBlBVbpWQ=
-----END RSA PRIVATE KEY-----

e questo PEM privato

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCAAZXj8YAEQya8jF8l6Hy56BcRBgplxPd8ZM5LIAWm0w1k/CgB
gvrI28W+5orOyqST2gC4EBEGmLw9s3NC8McL3qqFIQvd6SpWzCJEiI9n+wCkJLYf
715t6BwZo8F82AdqRHwL1lL0T4JeakgcFO5zno2l/NYKpZtS78vIq2F8pwIDAQAB
AoGAIAdFh+lPTMG4mYjN7eBEBQgrbVkDlP85pWhbrbRvdZRtT41APVCWi1diHSf2
J1PQ5iWv9F4gxHPG9fFGr8MrKk+jCM0/rDJsN7yC1yiSerS9zNvoSWu4D1cizRn2
ZOFi+TJZVHAoVvuh1vJdsFLkDmfoXelR6v6ojQxp6IftblECQQD7W4F92yHVIkRt
ZEz5TMYxtFF2d5uwi6XA/1MDuWpK0dK20a7DUGmgQ8faNfSZ/Dr1JmLx0OK/+Ocg
5HnzNo5NAkEAgl7Wa/Lr0TUH5h4L3SsJ1aeYUC6CbzJHBpNTvhuC7YEcs0AJL2k3
qYSM8VpU7q9iGHvfQhnKH9eBXlQbJBt4wwJBAJ1Pj6Ns2afCYoD0HRiJbCD/cVxr
Tw0W2Q4IvbO+/z8EQpQYdv/V+8VJpnJzAjq9GUkEVThyOvdal4yGcaw9oKECQC8V
/a+jXxSCaMXuGC7bOoQWMebTxXxP1mNDlr1UxmbteOYsvKSJBfeNzjHlhENoyK87
HhmLovr5JNpi2iKiYW0CQDyniRLXCyBVayJd3QkuMFKVNUuOytXUFWNXTpLA1Nbb
2K+leKb2KSyyEmRFC2X+QwF9ZBP1C3b0lgBBlBVbpWdddddddddddddddddddddddddQ=
-----END RSA PRIVATE KEY-----

entrambi generano lo stesso PEM pubblico generato:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAAZXj8YAEQya8jF8l6Hy56BcR
BgplxPd8ZM5LIAWm0w1k/CgBgvrI28W+5orOyqST2gC4EBEGmLw9s3NC8McL3qqF
IQvd6SpWzCJEiI9n+wCkJLYf715t6BwZo8F82AdqRHwL1lL0T4JeakgcFO5zno2l
/NYKpZtS78vIq2F8pwIDAQAB
-----END PUBLIC KEY-----

Ho pensato che cambiare un personaggio del PEM privato avrebbe comportato un PEM pubblico completamente nuovo. Mi manca qualcosa o alcuni caratteri possono essere modificati senza influire sul risultato PEM pubblico?

La libreria JavaScript che sto utilizzando per generare il PEM pubblico da un PEM privato è il nodo-rsa di rzcoder , che utilizza la libreria crittografica jsbn di Tom Wu .

    
posta trusktr 22.04.2014 - 10:03
fonte

2 risposte

3

Il formato PEM è un residuo di un vecchio standard dimenticato chiamato Privacy Enhanced Mail (non è mai stato ampiamente adottato, ma servito come ispirazione per ulteriori protocolli, in particolare S / MIME e PGP). Una chiave privata RSA in PEM è in realtà la Base64 codifica del DER codifica di una ASN.1 struttura che sembra in questo modo:

RSAPrivateKey ::= SEQUENCE {
    version           Version,
    modulus           INTEGER,  -- n
    publicExponent    INTEGER,  -- e
    privateExponent   INTEGER,  -- d
    prime1            INTEGER,  -- p
    prime2            INTEGER,  -- q
    exponent1         INTEGER,  -- d mod (p-1)
    exponent2         INTEGER,  -- d mod (q-1)
    coefficient       INTEGER,  -- (inverse of q) mod p
    otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

(Questo è preso direttamente da PKCS # 1 , lo standard RSA più usato.)

Ciò che deve essere notato qui è che una chiave RSA privata consiste in numerosi campi, tra cui il modulo e l'esponente pubblico. Ciò significa che la chiave pubblica può essere semplicemente "estratta" dalla chiave privata.

Con i tuoi personaggi in più, hai fatto due cose:

  1. Hai "danneggiato" il valore coefficient . Questo è l'inverso di q modulo p , dove p e q sono i fattori primi del modulo. Viene utilizzato per operazioni con chiave privata, in particolare quelle implementate con il CRT (un trucco elegante che quadruplica la velocità del privato operazioni chiave).

  2. Hai aggiunto "garbage" dopo la struttura ASN.1. La codifica DER ha intestazioni di lunghezza esplicite, quindi il decoder sa bene dove si ferma la struttura principale.

Nel tuo caso, il decodificatore PEM / DER che usi sembra semplicemente ignorare la spazzatura finale (alcune altre librerie rifiuterebbero la chiave con un errore, ad esempio quello è OpenSSL fa). Poiché l'estrazione della chiave pubblica non utilizza coefficient , ottieni la stessa chiave pubblica della chiave privata non danneggiata. Tuttavia, se provi a utilizzare la tua chiave privata modificata, è probabile che non otterrai risultati corretti (a seconda che la tua implementazione utilizzi la CRT o meno).

    
risposta data 22.04.2014 - 14:44
fonte
1

A volte, dipende da cosa cambi. Un normale file di chiavi private RSA è una struttura di dati ASN.1 di forma DER codificata PEM che contiene un numero di versione , più otto componenti chiave numerici, nell'ordine:

  1. versione (0)
  2. il modulo, n
  3. esponente pubblico, e
  4. l'esponente privato, d
  5. la coppia di primi originali usata per generare la chiave, p e q
  6. tre valori aggiuntivi utilizzati nei calcoli CRT , e1 , e2 , q

Solo la prima coppia di numeri ( n e e ) finisce nella chiave pubblica, a patto che rimangano invariati, l'output sarà lo stesso. (Non stai usando un certificato X.509 firmato qui, se tu fossi in quel momento altri dettagli come il numero di serie, gli intervalli di date e altro ancora devono essere uguali per mantenere il vero per il certificato.)

Si sta modificando uno dei cinque valori relativi al CRT alla fine della struttura, questo si tradurrà in errori o risultati errati quando qualcosa tenta di usare quelli per la decrittografia, che è quasi certamente ogni libreria standard dato il guadagno di prestazioni. (Questi numeri servono solo per l'ottimizzazione, dal momento che numeri abbastanza lunghi sono intatti per recuperare i numeri primi, la decrittografia è possibile.)

Inoltre, il formato DER ASN.1 utilizza lunghezze "contate", il tipo di dati e la lunghezza appaiono in una breve intestazione che precede ogni valore, la maggior parte del tuo contenuto extra verrà visualizzato come junk finale e potrebbe essere ignorato. Dovresti anche osservare la struttura del pad base64 (che non sei, quindi il tuo decoder dovrebbe essere lamentarsi dell'input non valido con i dati della chiave modificata).

È possibile ispezionare la struttura ASN.1 delle chiavi convertendole in DER binario (cioè decodifica base64 del carico utile) e quindi utilizzando dumpasn1 .

openssl rsa -in prv.pem -outform DER -out prv.der
dumpasn1 -tilda prv.der 
openssl rsa -pubin -in pub.pem -outform DER -out pub.der
dumpasn1 -tilda pub.der 

openssl x509 gestirà solo certificati attendibili o firmati e non convertirà questa chiave pubblica, openssl rsa -pubin elabora chiavi pubbliche non firmate. Puoi fare qualcosa di simile a quanto sopra con openssl asn1parse , ma non è così informativo o semplice da usare per questo.

    
risposta data 22.04.2014 - 14:59
fonte

Leggi altre domande sui tag