40

我正在用 Python 制作一个程序,通过安装程序分发给 Windows 用户。

该程序需要能够每天下载使用用户公钥加密的文件,然后对其进行解密。

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

这是 pyCrypto 会做的事情吗(文档很模糊)?还有其他纯 Python 库吗?任何语言的独立命令行工具怎么样?

到目前为止,我所看到的只是 GNUPG,但在 Windows 上安装它会对注册表产生影响,并且到处抛出 dll,然后我不得不担心用户是否已经安装了这个,如何备份他们现有的密钥环等。我宁愿只需拥有一个 python 库或命令行工具并自己管理密钥。

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

4

7 回答 7

37

您不需要PyCryptoor PyMe,尽管这些软件包可能是好的 - 您将在 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's 的版本 ( ) GPG.py,它使用该subprocess模块。它在 Windows 下运行良好,至少对我来说是这样——我用它来执行以下操作:

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

我拥有的模块现在不适合展示,因为它包含一些不应该存在的其他内容 - 这意味着我目前无法按原样发布它。在某个时候,也许在接下来的几周内,我希望能够整理它,添加更多单元测试(例如,我没有任何用于签名/验证的单元测试)并发布它(或者在原始PyCrypto许可证或类似的商业友好许可证)。如果您迫不及待,请使用 Traugott 的模块并自己修改它 - 使其与subprocess模块一起工作并没有太多工作。

这种方法比我考虑并尝试过的其他方法(例如SWIG基于 - 的解决方案或需要使用MinGW/构建的解决方案)痛苦得多。MSYS我对用其他语言编写的系统使用了相同的 ( gpg.exe/ ) 方法,例如,同样没有痛苦的结果。iconv.dllC#

PS 它适用于 Python 2.4 以及 Python 2.5 及更高版本。没有用其他版本测试过,虽然我没有预见到任何问题。

于 2009-06-27T22:12:35.683 回答
28

经过大量挖掘,我找到了一个适合我的包。虽然说支持生成密钥,但我没有测试。但是,我确实设法解密了使用 GPG 公钥加密的消息。这个包的优点是它不需要机器上的 GPG 可执行文件,并且是 OpenPGP 的基于 Python 的实现(而不是可执行文件的包装器)。我使用 GPG4win 和 kleopatra for windows 创建了私钥和公钥,请参阅下面的代码。

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)

虽然这个问题很老了。我希望这对未来的用户有所帮助。

于 2017-10-10T11:41:13.180 回答
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
于 2009-06-24T08:30:10.367 回答
3

PyMe确实声称与 Python 2.4 完全兼容,我引用:

PyMe 的最新版本(在撰写本文时)是 v0.8.0。它的 Debian 二进制发行版是使用 SWIG v1.3.33 和 GCC v4.2.3 编译的,用于 GPGME v1.1.6 和 Python v2.3.5、v2.4.4 和 v2.5.2(当时以“不稳定”发行版提供)。它的 Windows 二进制发行版是使用 SWIG v1.3.29 和 MinGW v4.1 编译的,用于 GPGME v1.1.6 和 Python v2.5.2(尽管安装了相同的二进制文件并且在 v2.4.2 中也可以正常工作)。

我不确定你为什么说“它似乎与我必须使用的 Python 2.4 不兼容”——请具体说明一下?

是的,它确实作为 GPGME 上的半 Pythonic (SWIGd) 包装器存在——一旦你拥有一个基本上可以完成这项工作的 C 库,这是开发 Python 扩展的一种流行方式。

PyPgp有一个更简单的方法——这就是为什么它是一个单一的、简单的 Python 脚本:基本上它只是对命令行 PGP 命令进行“shell out”。例如,解密只是:

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

即,将加密后的密文写入 的标准输入pgpv -f,读取 pgpv 的标准输出作为解密后的明文。

PyPgp 也是一个非常古老的项目,尽管它的简单性意味着使其与现代 Python 一起工作(例如,子进程而不是现在已弃用的 os.popen2)并不难。但是您仍然需要安装PGP,否则 PyPgp 不会做任何事情;-)。

于 2009-06-24T16:03:44.223 回答
3

M2Crypto有 PGP 模块,但我实际上从未尝试过使用它。如果您尝试了它并且它有效,请告诉我(我是当前的 M2Crypto 维护者)。一些链接:

更新: PGP 模块不提供生成密钥的方法,但推测这些可以使用较低级别的RSADSA等模块创建。我不知道 PGP 的内幕,所以你必须挖掘细节。此外,如果您知道如何使用 openssl 命令行命令生成这些,那么将其转换为 M2Crypto 调用应该相当容易。

于 2009-06-25T04:10:59.127 回答
3

正如其他人所指出的,PyMe 是这方面的规范解决方案,因为它基于 GpgME,它是 GnuPG 生态系统的一部分。

对于 Windows,我强烈建议使用Gpg4win作为 GnuPG 发行版,原因有两个:

它基于 GnuPG 2,其中包括gpg2.exe,它可以(最后,我可能会添加 :)gpg-agent.exe按需启动(gpg v1.x 不能)。

其次,它是 GnuPG 开发人员唯一的官方 Windows 版本。例如,它完全从 Linux 交叉编译到 Windows,因此在准备它时没有使用任何非自由软件(对于安全套件来说非常重要:)。

于 2009-07-31T18:26:43.300 回答
1

仅使用导出的公钥文件而不使用密钥环进行签名。

使用 PGPy 0.5.2(纯 Python GPG RFC 实现):

key_fpath = './recipient-PUB.gpg'
     
rsa_pub, _ = pgpy.PGPKey.from_file(rkey_fpath)
rkey = rsa_pub.subkeys.values()[0]                                                                                                     
     
text_message = pgpy.PGPMessage.new('my msg')
encrypted_message = rkey.encrypt(text_message)
print encrypted_message.__bytes__()

使用 gpg 1.10.0(gpgme Python 绑定 - 前 PyME):

rkey_fpath = './recipient-PUB.gpg'
cg = gpg.Context()
rkey = list(cg.keylist(source = rkey_fpath))                                                                                                                
 
ciphertext, result, sign_result = cg.encrypt('my msg', recipients=rkey, sign=False, always_trust=True)
print ciphertext

for 循环中的一个简单基准测试告诉我,对于我的系统上的这个简单操作,PGPy 比 gpgme Python 绑定快约 3 倍(请不要接受这个陈述,因为 X 比 Y 快:我将邀请您在您的环境中进行测试)。

于 2020-06-21T20:51:31.077 回答