Comment faire PGP en Python (générer des clés, chiffrer/déchiffrer)
je crée un programme en Python pour être distribué aux utilisateurs de windows via un installateur.
le programme doit pouvoir télécharger un fichier chaque jour chiffré avec la clé publique de l'utilisateur et ensuite 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échiffrer des fichiers cryptés avec la clé publique.
est-ce quelque chose que phycrypto va faire (la documentation est nébuleuse)? Existe-il d'autres pur Python les bibliothèques? Que diriez-vous d'un outil en ligne de commande autonome dans n'importe quelle langue?
Tout ce que j'ai vu jusqu'à présent était GNUPG, mais l'installation qui sur Windows fait des choses au registre et jette dll partout, et puis je dois me soucier de savoir si l'Utilisateur a déjà ce installé, comment sauvegarder leurs keyrings existants, etc Je préférerais avoir une bibliothèque python ou un outil en ligne de commande et gérer les clés moi-même.
mise à jour: pyME peut fonctionner mais il ne semble pas compatible avec Python 2.4 que je dois utiliser.
6 réponses
Vous n'avez pas besoin PyCrypto
ou PyMe
, bien que ces paquets puissent être-vous aurez toutes sortes de problèmes de construction sous Windows. 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 -gpg.exe
et iconv.dll
de la distribution sont suffisantes, et vous avez juste besoin de les avoir quelque part dans le chemin ou accédé à partir de votre code Python en utilisant un chemin complet. Aucune modification de la base de registre sont nécessaires, 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é écrite à l'origine par Andrew Kuchling, améliorée par Richard Jones et améliorée par Steve Traugott. Il est disponible ici, mais comme-est il n'est pas adapté pour les fenêtres parce qu'il utilise os.fork()
. Bien que faisant partie à l'origine de PyCrypto
,il est complètement indépendant des autres parties de .
j'ai une version (gnupg.py
) provenant de Traugott GPG.py
, qui utilise le subprocess
module. Il fonctionne très bien sous Windows, du moins pour mes besoins - Je l'utilise pour faire ce qui suit:
- gestion des clés-production, listage, exportation, etc.
- importer les clés d'une source externe (p. ex. les clés publiques reçues d'une entreprise partenaire)
- Chiffrer et déchiffrer les données
- signer et vérifier signatures
le module que j'ai n'est pas idéal pour le moment, parce qu'il inclut d'autres choses qui ne devraient pas être là - ce qui veut dire que je ne peux pas le libérer tel quel pour le moment. À un moment donné, peut-être dans les deux prochaines semaines, j'espère être en mesure de le ranger, ajouter quelques tests unitaires supplémentaires (je n'ai pas de tests unitaires pour sign/verify, par exemple) et le libérer (soit sous l'original PyCrypto
licence ou une licence commerciale similaire). Si vous ne pouvez pas attendre, allez avec le module de Traugott et le modifier vous-même - il n'était pas trop de travail pour le faire fonctionner avec le subprocess
module.
cette approche a été beaucoup moins douloureuse que les autres (par exemple SWIG
solutions ou des solutions qui nécessitent la création de MinGW
/MSYS
), que j'ai étudié et expérimenté. J'ai utilisé le même (gpg.exe
/iconv.dll
) approche des systèmes écrits dans d'autres langues, par exemple,C#
, avec des résultats tout aussi indolores.
P. S. Il fonctionne avec Python 2.4 ainsi que Python 2.5 et ultérieur. Pas testé avec d'autres versions, bien que je ne prévoie aucun problème.
Phycrypto supporte PGP-bien que vous devriez le tester pour vous assurer qu'il fonctionne selon vos spécifications.
bien que la documentation soit difficile à trouver, si vous regardez à travers Util/test.py (le script de test du module), vous pouvez trouver un exemple rudimentaire de leur support 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
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
M2Crypto a un module PGP, mais je n'ai jamais essayé de l'utiliser. Si vous l'essayez, et il fonctionne, s'il vous plaît laissez-moi savoir (je suis l'actuel M2Crypto responsable). Quelques liens:
mise à Jour: le module PGP ne fournit pas de moyens pour générer des clés, mais probablement celles-ci pourraient être créées avec le plus bas niveau RSA, DSA etc. module. Je ne connais pas L'intérieur de PGP, donc vous devez déterrer les détails. En outre, si vous savez comment les générer en utilisant des commandes en ligne de commande openssl, il devrait être assez facile de les convertir en appels M2Crypto.
PyMe revendique la pleine compatibilité avec Python 2.4, et je cite:
la dernière version de PyMe (à partir de l'écriture) est v0.8.0. Son binaire la distribution 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 en distribution "instable" à l'époque). Sa distribution binaire Pour Windows a été compilé 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 obtenir installé et fonctionne très bien dans v2.4.2 bien.)
Je ne suis pas sûr pourquoi vous dites "il ne semble pas être compatible avec Python 2.4 que je dois utiliser" -- détails s'il vous plaît?
et oui il existe comme un enveloppeur semi-pythonique (SWIGd) sur GPGME -- c'est une façon 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 -- pourquoi il s'agit d'un simple, simple script Python: fondamentalement, il ne fait rien de plus que "shell out" pour les commandes PGP en ligne de commande. Par exemple, le décryptage est juste:
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 code crypté à l'entrée standard de pgpv -f
, lire pgpv de sortie standard en la restitution du texte en clair.
PyPgp est également un projet très ancien, bien que sa simplicité signifie qu'il fonctionne avec Python moderne (par exemple, subprocess au lieu de now-deprecated os.popen2) ne serait pas difficile. Mais vous n'avez toujours besoin d' PGP installé, ou PyPgp de ne pas faire n'importe quoi;-).
Pour Windows, je vous recommande fortement d'utiliser Gpg4win comme la distribution GnuPG, pour deux raisons:
il est basé sur GnuPG 2, qui, entre autres choses, comprend gpg2.exe
qui peut (enfin, je pourrais ajouter :) start gpg-agent.exe
à la demande (gpg v1.x ne peut pas faire).
après avoir beaucoup creusé, j'ai trouvé un paquet qui marchait pour moi. Bien qu'il soit dit pour soutenir la génération de clés, Je ne l'ai pas testé. Cependant j'ai réussi à déchiffrer un message qui a été chiffré en utilisant une clé publique GPG. L'avantage de ce paquet est qu'il n'a pas besoin d'un fichier exécutable GPG sur la machine, et est une implémentation basée sur Python de L'OpenPGP (plutôt qu'un enveloppeur 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.