2014-05-24 13 views
6

sto generando una chiave con OpenSSL, fornendo la password da stdin:Come utilizzare la chiave privata RSA crittografata con PyCrypto?

openssl genpkey -algorithm RSA -out private-key.pem -outform PEM -pass stdin -des3 -pkeyopt rsa_keygen_bits:4096 

La chiave appare allora come:

-----BEGIN ENCRYPTED PRIVATE KEY----- 
XXX... 
-----END ENCRYPTED PRIVATE KEY----- 
codice

mio Python assomiglia:

from Crypto.PublicKey import RSA 
# ... 
f = open('private-key.pem', 'r') 
r = RSA.importKey(f.read(), passphrase='some-pass') 
f.close() 

ma Ricevo un'eccezione:

File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 665, in importKey 
    return self._importKeyDER(der) 
    File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 588, in _importKeyDER 
    raise ValueError("RSA key format is not supported") 
ValueError: RSA key format is not supported 

Cosa c'è che non va?

È possibile generare una chiave RSA crittografata, memorizzarla in un file e successivamente utilizzarla con PyCrypto? È possibile farlo con OpenSSL? Quali formati sono supportati?

L'importazione della chiave pubblica funziona correttamente, tuttavia non è crittografata.

+0

interessante, a giudicare dalla traccia dello stack si sta tentando di importarlo in formato binario DER, non in PEM.Sei sicuro di fornire il file corretto? –

risposta

4

Ipotesi # 1

Dopo aver guardato al codice sorgente, penso, ho risolto il mistero. Il modo in cui l'importazione funziona per le chiavi PEM crittografate con una password è che il PEM viene decrittografato su DER e dopo che viene chiamata la funzione importKeyDER. Se la password fornita non è corretta, anche il formato della rappresentazione DER generata non sarà corretto e otterresti un'eccezione che hai fornito. Per confermare che, ho eseguito due test rapidi di seguito:

>>> from Crypto.PublicKey import RSA 
>>> f = open('<some-path>/private-key.pem','r') 
>>> r=RSA.importKey(f.read(),passphrase='foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 665, in importKey 
    return self._importKeyDER(der) 
    File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 588, in _importKeyDER 
    raise ValueError("RSA key format is not supported") 
ValueError: RSA key format is not supported 
>>> f = open('<some-path>/private-key.pem','r') 
>>> r=RSA.importKey(f.read(),passphrase='<valid-pass-phrase>') 
>>> r 
<_RSAobj @0xb7237b2c n(4096),e,d,p,q,u,private> 

Dopo aver ricevuto la PEM da parte dell'autore, mi sono reso conto che Ipotesi # 1 non è valida per il suo caso. Voglio ancora tenerlo qui come una possibile ragione di errore di importazione, quindi altri utenti sono a conoscenza.

Ipotesi n. 2 - questo è il caso dell'autore.

RSA.py cerca il seguente nel file PEM per determinare quale tipo di crittografia è stato applicato alla PEM:

Proc-Type: 4,ENCRYPTED 

Quando il tasto viene generato utilizzando "OpenSSL genrsa ..." di comando, questa stringa è presente in PEM in chiaro, tuttavia quando viene utilizzato "opensl genpkey ..." il "Proc-Type" non è presente.

RSA.py non prova nemmeno a decifrare il PEM se il "Proc-Type" non si trova:

# The encrypted PEM format 
    if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')): 
    DEK = lines[2].split(b(':')) 
    .... 

Quindi, la mia conclusione in questo momento è che le chiavi generate da "OpenSSL genpkey" non sono supportati da PyCrypto v 2.6.1.

Aggiornamento importante

E funziona nella versione più recente di 2.7a1 pycrypto. Potete scaricarlo da qui: http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.7a1.tar.gz

>>> f = open('key.pem','r') 
>>> r = RSA.importKey(f.read(), passphrase='123456') 
>>> r 
<_RSAobj @0xb6f342ec n(2048),e,d,p,q,u,private> 
+0

Puoi provare con questa chiave? : http://pastebin.com/tcKJjdmw La password è '123456'. Funziona con il comando: openssl rsa -inform PEM -outform PEM -in private-key.pem -pubout, ma non con PyCrypto. – STF

+0

quale versione di openssl usi? –

+0

Controlla RSA.py ancora una volta e trova che cerca "Proc-Type: 4, ENCRYPTED". Se non lo trova, non tratterà nemmeno PEM come crittografato. Questo è ciò che ha generato il mio openssl: "----- INIZIA A PRIVATO RSA ----- Proc-Type: 4, DEK-Info CRITICATO: DES-EDE3-CBC, AC78286040A62849". Sembra che la nuova versione di openssl usi un formato più recente. Prova il vecchio modo di generare chiavi RSA: "openssl genrsa -des3 -out privkey.pem 2048" –

2

un rapido aggiornamento per coloro che cercano di risolvere questo problema senza installare una versione sperimentale di lungo abbandonato pycrypto.La libreria può essere tranquillamente sostituita da pycryptodome (https://github.com/Legrandin/pycryptodome) - può fornire sia una sostituzione drop-in per pycrypto, che può essere utilizzata anche come libreria alternativa (pycryptodomex).

Problemi correlati