如何在Python中使用PGP(生成密钥,加密/解密)

44 投票
9 回答
114184 浏览
提问于 2025-04-15 12:23

我正在用Python写一个程序,打算通过安装包分发给Windows用户。

这个程序需要每天下载一个用用户的公钥加密的文件,然后再解密它。

所以我需要找一个Python库,能够生成公钥和私钥的PGP密钥,并且可以解密用公钥加密的文件。

pyCrypto能做到这一点吗(文档看起来不太清楚)?还有其他纯Python的库吗?有没有其他语言的独立命令行工具?

我目前只看到GNUPG,但在Windows上安装它会对注册表做一些修改,还会到处放dll文件,然后我还得担心用户是否已经安装了这个工具,如何备份他们现有的密钥环等等。我更希望能有一个Python库或者命令行工具,这样我就可以自己管理密钥。

更新:pyME可能可以用,但它似乎不兼容我必须使用的Python 2.4。

9 个回答

7

PyCrypto支持PGP功能,不过你最好自己测试一下,确保它能满足你的需求。

虽然文档不太好找,但如果你查看一下Util/test.py(这个模块的测试脚本),你会发现一个简单的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

此外,PublicKey/pubkey.py里有一些相关的方法:

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
39

经过大量的探索,我找到了一款对我有用的工具。虽然说它支持生成密钥,但我没有测试这个功能。不过,我成功解密了一个用GPG公钥加密的信息。这个工具的好处在于,它不需要在电脑上安装GPG的可执行文件,而是基于Python实现的OpenPGP(而不是简单地调用可执行文件)。
我是在Windows上使用GPG4win和kleopatra创建的私钥和公钥。
下面是我的代码。

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)

虽然这个问题已经很久了,但我希望这能帮助到未来的用户。

44

你不需要使用 PyCryptoPyMe 这些包,虽然它们可能不错,但在Windows上安装会遇到各种问题。与其走弯路,不如试试我用的方法?使用 gnupg 1.4.9。你不需要在用户的电脑上进行完整安装,只需从分发包中拿到 gpg.exeiconv.dll 就可以了,只要把它们放在路径中,或者在你的Python代码中用完整路径访问它们即可。也不需要修改注册表,所有的可执行文件和数据文件如果你愿意都可以放在一个文件夹里。

有一个模块叫 GPG.py,最初是Andrew Kuchling写的,后来Richard Jones改进过,Steve Traugott又进一步改进。这个模块可以在 这里找到,但原版不适合Windows,因为它使用了 os.fork()。虽然最初是 PyCrypto 的一部分,但它与 PyCrypto 的其他部分完全独立,只需要 gpg.exe/iconv.dll 就能正常工作

我有一个版本(gnupg.py),是基于Traugott的 GPG.py 修改的,使用了 subprocess 模块。它在Windows上运行得很好,至少对我来说是这样——我用它来做以下事情:

  • 密钥管理 - 生成、列出、导出等。
  • 从外部来源导入密钥(例如,从合作公司收到的公钥)
  • 加密和解密数据
  • 签名和验证签名

我现在的这个模块不是最理想的,因为它包含了一些不该有的东西——这意味着我现在不能直接发布。如果一切顺利,可能在接下来的几周内,我希望能整理一下,增加一些单元测试(例如,我没有针对签名/验证的单元测试),然后发布(可能会在原来的 PyCrypto 许可证下或者类似的商业友好许可证下)。如果你等不及了,可以直接用Traugott的模块,自己修改一下——让它与 subprocess 模块兼容并不太麻烦。

这种方法比其他方法要简单得多(例如基于 SWIG 的解决方案,或者需要使用 MinGW/MSYS 构建的解决方案),我曾考虑过并尝试过这些方法。我也在用其他语言写的系统中使用了同样的 gpg.exe/iconv.dll 方法,效果同样很好。

附言:它在Python 2.4和Python 2.5及以后的版本中都能工作。不过我没有测试其他版本,但我认为不会有问题。

撰写回答