web-dev-qa-db-fra.com

Comment faire PGP dans Python (générer des clés, chiffrer / déchiffrer)

Je fais un programme en Python pour être distribué aux utilisateurs de Windows via un programme d'installation.

Le programme doit pouvoir télécharger quotidiennement un fichier chiffré avec la clé publique de l'utilisateur, puis le déchiffrer.

J'ai donc besoin de trouver une bibliothèque Python qui me permettra de générer des clés PGP publiques et privées, et aussi de décrypter les fichiers cryptés avec la clé publique.

Est-ce quelque chose que pyCrypto fera (la documentation est nébuleuse)? Existe-t-il d'autres bibliothèques Python pures? Que diriez-vous d'un outil de ligne de commande autonome dans n'importe quelle langue?

Tout ce que j'ai vu jusqu'à présent, c'est GNUPG, mais l'installation sur Windows fait des trucs dans le registre et envoie des DLL partout, et ensuite je dois me demander si l'utilisateur a déjà installé cela, comment sauvegarder leurs trousseaux de clés existants, etc. Je préfère juste avoir une bibliothèque python ou un outil de ligne de commande et gérer moi-même les clés.

Mise à jour: pyME peut fonctionner mais il ne semble pas compatible avec Python 2.4 que je dois utiliser.

31
Greg

Vous n'avez pas besoin de PyCrypto ou PyMe, bien que ces packages puissent l'être - vous aurez toutes sortes de problèmes à construire sous Windows. Au lieu de cela, pourquoi ne pas éviter les trous de lapin et faire ce que j'ai fait? Utilisez gnupg 1.4.9. Vous n'avez pas besoin de faire une installation complète sur les machines des utilisateurs finaux - seulement gpg.exe Et iconv.dll De la distribution sont suffisants, et vous avez juste besoin de les avoir quelque part dans le chemin d'accès ou d'y accéder depuis votre Python utilisant un chemin d'accès complet. Aucune modification du registre n'est nécessaire, et tout (exécutables et fichiers de données) peut être confiné dans un seul dossier si vous le souhaitez.

Il y a un module GPG.py Qui a été écrit à l'origine par Andrew Kuchling, amélioré par Richard Jones et amélioré par Steve Traugott. Il est disponible ici , mais tel quel, il ne convient pas à Windows car il utilise os.fork(). Bien que faisant initialement partie de PyCrypto, , il est complètement indépendant des autres parties de PyCrypto et n'a besoin que de gpg.exe/iconv.dll pour fonctionner .

J'ai une version (gnupg.py) Dérivée de GPG.py De Traugott, qui utilise le module subprocess. Cela fonctionne bien sous Windows, au moins pour mes besoins - je l'utilise pour faire ce qui suit:

  • Gestion des clés - génération, listage, exportation etc.
  • Importer des clés à partir d'une source externe (par exemple, des clés publiques reçues d'une entreprise partenaire)
  • Chiffrer et déchiffrer les données
  • Signer et vérifier les signatures

Le module que j'ai n'est pas idéal pour montrer en ce moment, car il comprend d'autres éléments qui ne devraient pas être là - ce qui signifie que je ne peux pas le publier tel quel pour le moment. À un moment donné, peut-être au cours des prochaines semaines, j'espère pouvoir le ranger, ajouter quelques tests unitaires supplémentaires (je n'ai pas de tests unitaires pour signer/vérifier, par exemple) et le publier (soit sous la licence d'origine PyCrypto ou une licence commerciale similaire). Si vous ne pouvez pas attendre, allez avec le module de Traugott et modifiez-le vous-même - ce n'était pas trop de travail pour le faire fonctionner avec le module subprocess.

Cette approche a été beaucoup moins douloureuse que les autres (par exemple, les solutions basées sur SWIG, ou les solutions qui nécessitent une construction avec MinGW/MSYS), que j'ai envisagées et expérimentées. J'ai utilisé la même approche (gpg.exe/iconv.dll) Avec des systèmes écrits dans d'autres langues, par ex. C#, Avec des résultats tout aussi indolores.

P.S. Il fonctionne avec Python 2.4 ainsi que Python 2.5 et versions ultérieures. Non testé avec d'autres versions, bien que je ne prévois aucun problème).

28
Vinay Sajip

Après beaucoup de fouilles, j'ai trouvé un paquet qui fonctionnait pour moi. Bien qu'il soit censé prendre en charge la génération de clés, je ne l'ai pas testé. Cependant, j'ai réussi à déchiffrer un message chiffré à l'aide d'une clé publique GPG. L'avantage de ce package est qu'il ne nécessite pas de fichier exécutable GPG sur la machine, et est une implémentation basée sur Python d'OpenPGP (plutôt qu'un wrapper autour de l'exécutable). J'ai créé les clés privées et publiques en utilisant GPG4win et kleopatra pour Windows Voir mon code ci-dessous.

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)

Bien que la question soit très ancienne. J'espère que cela aidera les futurs utilisateurs.

8
Roee Anuar

PyCrypto prend en charge PGP - mais vous devez le tester pour vous assurer qu'il fonctionne selon vos spécifications.

Bien que la documentation soit difficile à trouver, si vous regardez dans Util/test.py (le script de test du module), vous pouvez trouver un exemple rudimentaire de leur prise en charge 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

De plus, PublicKey/pubkey.py fournit les méthodes pertinentes suivantes:

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
7
Jon

Comme d'autres l'ont noté, PyMe est la solution canonique pour cela, car il est basé sur GpgME, qui fait partie de l'écosystème GnuPG.

Pour Windows, je recommande fortement d'utiliser Gpg4win comme distribution GnuPG, pour deux raisons:

Il est basé sur GnuPG 2, qui comprend, entre autres, gpg2.exe, qui peut (enfin, je pourrais ajouter :) commencer gpg-agent.exe à la demande (gpg v1.x ne peut pas).

Et deuxièmement, c'est la seule version officielle de Windows par les développeurs GnuPG. Par exemple. il est entièrement compilé de Linux à Windows, donc pas un iota de logiciel non libre n'a été utilisé pour le préparer (assez important pour une suite de sécurité :).

3
Marc Mutz - mmutz

PyMe revendique une compatibilité totale avec Python 2.4, et je cite:

La dernière version de PyMe (à ce jour) est la v0.8.0. Sa distribution binaire pour Debian a été compilée avec SWIG v1.3.33 et GCC v4.2.3 pour GPGME v1.1.6 et Python v2.3.5, v2.4.4 et v2.5.2 (fourni dans 'unstable) Sa distribution binaire pour Windows a été compilée avec SWIG v1.3.29 et MinGW v4.1 pour GPGME v1.1.6 et Python v2.5.2 (bien que le même binaire soit installé et fonctionne également très bien dans la version 2.4.2).

Je ne sais pas pourquoi vous dites "cela ne semble pas être compatible avec Python 2.4 que je dois utiliser" - des détails s'il vous plaît?

Et oui, il existe en tant que wrapper semi-Pythonique (SWIGd) sur GPGME - c'est un moyen populaire de développer des extensions Python une fois que vous avez une bibliothèque C qui fait essentiellement le travail.

PyPgp a une approche beaucoup plus simple - c'est pourquoi c'est un seul et simple Python: en gros, il ne fait rien de plus que "Shell out" pour les commandes PGP en ligne de commande Par exemple, le déchiffrement est simplement:

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

c'est-à-dire, écrire le texte chiffré crypté dans l'entrée standard de pgpv -f, lit la sortie standard de pgpv comme texte en clair décrypté.

PyPgp est également un projet très ancien, bien que sa simplicité signifie que le faire fonctionner avec le moderne Python (par exemple, sous-processus au lieu de os.popen2 maintenant obsolète) ne serait pas difficile. Mais vous le faites toujours besoin de PGP installé, ou PyPgp ne fera rien ;-).

3
Alex Martelli

M2Crypto possède un module PGP, mais je n'ai en fait jamais essayé de l'utiliser. Si vous l'essayez et que cela fonctionne, faites-le moi savoir (je suis le responsable actuel de M2Crypto). Quelques liens:

Mise à jour: Le module PGP ne fournit pas de moyens de générer des clés, mais celles-ci pourraient probablement être créées avec le niveau inférieur RSA , DSA etc. modules. Je ne connais pas PGP à l'intérieur, alors il faudrait trouver les détails. De plus, si vous savez comment les générer à l'aide des commandes de ligne de commande openssl, il devrait être relativement facile de convertir cela en appels M2Crypto.

3
Heikki Toivonen