2009-06-19 5 views
26

Sto realizzando un programma in Python per essere distribuito agli utenti di Windows tramite un programma di installazione.Come fare PGP in Python (generare chiavi, crittografare/decodificare)

Il programma deve essere in grado di scaricare un file ogni giorno crittografato con la chiave pubblica dell'utente e quindi decrittografarlo.

Quindi ho bisogno di trovare una libreria Python che mi consenta di generare chiavi PGP pubbliche e private e anche di decodificare i file crittografati con la chiave pubblica.

È qualcosa che pyCrypto farà (la documentazione è nebulosa)? Ci sono altre librerie Python pure? Che ne dici di uno strumento da riga di comando standalone in qualsiasi lingua?

Tutto quello che ho visto finora è stato GNUPG ma l'installazione su Windows fa cose nel registro e getta dll ovunque, quindi devo preoccuparmi se l'utente ha già installato questo, come fare il backup dei portachiavi esistenti, ecc. Preferisco semplicemente avere una libreria Python o uno strumento da riga di comando e gestire personalmente le chiavi.

Aggiornamento: pyME potrebbe funzionare ma non sembra essere compatibile con Python 2.4 che devo usare.

risposta

24

Non è necessario PyCrypto o PyMe, anche se questi pacchetti potrebbero essere - si avranno tutti i tipi di problemi nella creazione di Windows. Invece, perché non evitare le buche dei conigli e fare quello che ho fatto? Utilizzare gnupg 1.4.9. Non è necessario eseguire un'installazione completa sui computer degli utenti finali: sono sufficienti solo gpg.exe e iconv.dll dalla distribuzione e è sufficiente averli da qualche parte nel percorso o accedere dal codice Python utilizzando un percorso completo. Non sono necessarie modifiche al registro e tutto (file eseguibili e file di dati) può essere limitato a una singola cartella, se lo si desidera.

C'è un modulo GPG.py che è stato originariamente scritto da Andrew Kuchling, migliorato da Richard Jones e ulteriormente migliorato da Steve Traugott. È disponibile here, ma non è adatto per Windows perché utilizza os.fork(). Sebbene sia originariamente parte di PyCrypto, , è completamente indipendente dalle altre parti di PyCrypto e richiede solo gpg.exe/iconv.dll per funzionare.

Ho una versione (gnupg.py) derivata da Traugott GPG.py, che utilizza il modulo subprocess. Funziona bene con Windows, almeno per i miei scopi - Io lo uso per effettuare le seguenti operazioni:

  • Gestione delle chiavi - generazione, profilo, export ecc
  • chiavi Importa da una fonte esterna (ad esempio, le chiavi pubbliche ricevute da una società partner)
  • crittografare e decrittografare i dati
  • firmare e verificare firme

Il modulo che ho non è l'ideale per mostrare in questo momento, perché comprende alcune altre cose che non dovrebbe essere ther e - il che significa che non posso rilasciarlo così com'è al momento.Ad un certo punto, forse nelle prossime due settimane, spero di essere in grado di riordinarlo, aggiungere qualche altro test unitario (non ho alcun test unitario per il segno/verificare, per esempio) e rilasciarlo (o sotto la licenza originale PyCrypto o una simile licenza commerciale-amichevole). Se non puoi aspettare, usa il modulo di Traugott e modificalo da solo: non è stato troppo lavoro per farlo funzionare con il modulo subprocess.

Questo approccio è stato molto meno doloroso rispetto agli altri (ad esempio SWIG soluzioni basate, o soluzioni che richiedono edificio con MinGW/MSYS), che ho considerato e sperimentato. Ho utilizzato lo stesso approccio (gpg.exe/iconv.dll) con sistemi scritti in altre lingue, ad es. C#, con risultati altrettanto indolore.

P.S. Funziona con Python 2.4 e Python 2.5 e versioni successive. Non testato con altre versioni, anche se non prevedo alcun problema.

+0

Grazie, sembra perfetto. Non avevo idea di poter estrarre l'exe dal gpg. Dove metterà il portachiavi? Questo metodo causerà problemi se l'utente ha già installato gpg? Qualche possibilità di vedere come il tuo codice genera le chiavi e le importazioni principali? – Greg

+0

Assicurati inoltre di aggiornarci qui quando rilasci il tuo codice finale. – Greg

+0

Quando chiami gpg, specifica il percorso in cui desideri che i portachiavi siano nascosti usando l'argomento --homedir. (Questo è già fatto per te usando il modulo di Traugott - c'è una classe GPG il cui costruttore prende un parametro gnupghome che puoi impostare su questa directory.) Il pubring.gpg, secring.gpg e trustdb.gpg vengono creati nella cartella specificata da - -homedir. Non credo che questo causerà un problema se l'utente ha già installato gpg - l'argomento --homedir dovrebbe sovrascrivere qualsiasi valore nel registro. –

6

PyCrypto supporta PGP, anche se dovresti testarlo per assicurarti che funzioni secondo le tue specifiche.

Anche se la documentazione è difficile da trovare, se si guarda attraverso Util/test.py (lo script di test del modulo), è possibile trovare un esempio rudimentale di loro supporto PGP:

if verbose: print ' PGP mode:', 
obj1=ciph.new(password, ciph.MODE_PGP, IV) 
obj2=ciph.new(password, ciph.MODE_PGP, IV) 
start=time.time() 
ciphertext=obj1.encrypt(str) 
plaintext=obj2.decrypt(ciphertext) 
end=time.time() 
if (plaintext!=str): 
    die('Error in resulting plaintext from PGP mode') 
print_timing(256, end-start, verbose) 
del obj1, obj2 

Futhermore, PublicKey/pubkey.py prevede i seguenti metodi rilevanti:

def encrypt(self, plaintext, K) 
def decrypt(self, ciphertext): 
def sign(self, M, K): 
def verify (self, M, signature): 
def can_sign (self): 
    """can_sign() : bool 
    Return a Boolean value recording whether this algorithm can 
    generate signatures. (This does not imply that this 
    particular key object has the private information required to 
    to generate a signature.) 
    """ 
    return 1 
+2

Non vedo un modo per generare chiavi o accettare la chiave pubblica di un'altra parte per crittografare i dati con. Qualche idea? – Greg

+3

No, MODE_PGP in PyCrypto è un codice sperimentale precedente che probabilmente non ha mai funzionato correttamente. (Vedi https://bugs.launchpad.net/pycrypto/+bug/996814). Non usarlo Lo rimuoveremo presto da PyCrypto. – dlitz

+1

Allora cosa suggerisci, @dlitz? – raylu

2

PyMe ha la pretesa piena compatibilità con Python 2.4, e cito:

L'ultima versione di PyMe (a partire da questa scrittura ) è v0.8.0. Il suo binario distribuzione Debian è stato compilato con SWIG v1.3.33 e GCC v4.2.3 per GPGME v1.1.6 e Python v2.3.5, v2.4.4 e v2.5.2 (fornito in distribuzione 'unstable' al tempo). La sua distribuzione binaria per Windows è stato compilato con SWIG v1.3.29 e MinGW v4.1 per GPGME v1.1.6 e Python v2.5.2 (anche se lo stesso binario ottenere installato e funziona bene in v2.4.2 come bene) .

Non sono sicuro del motivo per cui si dice "non sembra essere compatibile con Python 2.4 che devo usare" - specifiche per favore?

E sì, esiste come un wrapper semi-Pythonic (SWIGd) su GPGME - questo è un modo popolare per sviluppare estensioni Python una volta che si dispone di una libreria C che fondamentalmente fa il lavoro.

PyPgp ha un approccio molto più semplice - ecco perché è un singolo, semplice script Python: in pratica non fa altro che "shell out" ai comandi PGP della riga di comando. Ad esempio, la decrittografia è solo:

def decrypt(data): 
    "Decrypt a string - if you have the right key." 
    pw,pr = os.popen2('pgpv -f') 
    pw.write(data) 
    pw.close() 
    ptext = pr.read() 
    return ptext 

, ad es., scrivere il testo cifrato crittografato sullo standard input di pgpv -f, leggere l'output standard di pgpv come testo in chiaro decrittografato.

PyPgp è anche un progetto molto antica, anche se la sua semplicità significa che farlo funzionare con Python moderna (ad esempio, invece di sottoprocesso os.popen2 ormai obsoleto) non sarebbe difficile. Ma hai ancora bisogno di PGP installato, o PyPgp non farà nulla ;-).

+0

PyMe era questo problema: http://stackoverflow.com/questions/1030297/how-to-make-a-pyme-python-library-run-in-python-2-4-on-windows – Greg

+0

Sì, il reclamo che ho citato (su Windows, in particolare) è infondato (in Windows, solo, le estensioni devono essere compilate per specifiche versioni di Python, quindi una compilata per 2.5 non funzionerà per 2.4). Tutto ciò che serve è ricompilare (che richiede MSVC 6.0). –

3

M2Crypto ha un modulo PGP, ma in realtà non ho mai provato a usarlo. Se lo provi e funziona, faccelo sapere (sono l'attuale manutentore di M2Crypto). Alcuni link:

Update: Il modulo PGP non fornisce modi per generare le chiavi, ma presumibilmente questi potrebbe essere creato con il livello più basso RSA , DSA moduli ecc. Non conosco le intestazioni PGP, quindi dovresti scavare nei dettagli. Inoltre, se si sa come generare questi comandi usando i comandi della riga di comando di openssl, dovrebbe essere ragionevolmente facile convertirlo in chiamate M2Crypto.

+0

Hmm, sembrava promettente ma non vedo come generare le chiavi. – Greg

+0

Potrebbe essere possibile generare le chiavi con i moduli RSA, DSA, ecc. Di livello inferiore. –

2

Come altri hanno notato, PyMe è la soluzione canonica per questo, poiché si basa su GpgME, che fa parte dell'ecosistema GnuPG.

Per Windows, vi raccomando vivamente di utilizzare Gpg4win come la distribuzione di GnuPG, per due motivi:

Si basa su GnuPG 2, che, tra le altre cose, include gpg2.exe, che può (finalmente, aggiungo io:) avvia gpg-agent.exe su richiesta (gpg v1.x non può).

In secondo luogo, è l'unica build ufficiale di Windows degli sviluppatori GnuPG. Per esempio. è interamente cross-compilato da Linux a Windows, quindi non è stata utilizzata una quantità di software non libero per la sua preparazione (cosa abbastanza importante per una suite di sicurezza :).

1

Dopo un sacco di scavo, ho trovato un pacchetto che ha funzionato per me. Anche se si dice che supporti la generazione di chiavi, non l'ho testato. Tuttavia, sono riuscito a decodificare un messaggio crittografato utilizzando una chiave pubblica GPG. Il vantaggio di questo pacchetto è che non richiede un file eseguibile GPG sulla macchina ed è un'implementazione basata su Python di OpenPGP (piuttosto che un wrapper attorno all'eseguibile). Ho creato le chiavi private e pubbliche utilizzando GPG4win e kleopatra per windows Vedere il mio codice qui sotto.

import pgpy 
emsg = pgpy.PGPMessage.from_file(<path to the file from the client that was encrypted using your public key>) 
key,_ = pgpy.PGPKey.from_file(<path to your private key>) 
with key.unlock(<your private key passpharase>): 
    print (key.decrypt(emsg).message) 

Anche se la domanda è molto antica. Spero che questo aiuti i futuri utenti.

+0

Grazie per le informazioni. Questo può effettivamente eseguire la crittografia utilizzando la chiave pubblica? Inoltre, un link al pacchetto potrebbe essere utile. – lazyList

+0

@lazyList vedere qui: https://github.com/SecurityInnovation/PGPy –

+0

Grazie @Roee Anuar. Già usato per costruire un programma di protezione con password basato su PGP. Apprezzo l'aiuto. – lazyList