我正在用Python创建一个程序,通过安装程序分发给Windows用户。
程序需要能够每天下载使用用户公钥加密的文件,然后解密。
所以我需要找到一个Python库,让我生成公共和私有PGP密钥,并解密用公钥加密的文件。
这是pyCrypto会做的事情(文档是模糊的)?还有其他纯Python库吗?如何使用任何语言的独立命令行工具?
到目前为止,我所看到的只是GNUPG,但在Windows上安装它会对注册表产生影响,并且无处不在地抛出dll,然后我不得不担心用户是否已经安装了这个,如何备份现有的密钥环等等。我宁愿只有一个python库或命令行工具,并自己管理密钥。
更新:pyME可能有效,但它似乎与我必须使用的Python 2.4兼容。
答案 0 :(得分:27)
您不需要PyCrypto
或PyMe
,虽然这些软件包可能不错,但您在Windows下会遇到各种各样的问题。相反,为什么不避免兔子洞,做我做的事情?使用gnupg 1.4.9
。您不需要在最终用户计算机上进行完整安装 - 只需从发行版中gpg.exe
和iconv.dll
就足够了,您只需将它们放在路径中的某个位置或从Python访问即可使用完整路径名的代码。无需更改注册表,如果需要,可以将所有内容(可执行文件和数据文件)限制在单个文件夹中。
有一个模块GPG.py
,最初由Andrew Kuchling编写,由Richard Jones改进,并由Steve Traugott进一步改进。它可用here,但因为它不适合Windows,因为它使用os.fork()
。虽然最初是PyCrypto
的一部分,但完全独立于PyCrypto
的其他部分,并且只需要gpg.exe / iconv.dll才能工作。
我有一个源自Traugott gnupg.py
的版本(GPG.py
),该版本使用subprocess
模块。它在Windows下工作正常,至少在我的目的 - 我用它来做以下事情:
我所获得的模块现在并不理想,因为它包含了其他一些不应该存在的东西 - 这意味着我暂时无法释放它。在某些时候,也许在接下来的几周内,我希望能够整理它,添加一些单元测试(例如我没有任何用于签名/验证的单元测试)并释放它(在原始PyCrypto
许可证或类似的商业友好许可证)。如果您迫不及待,请使用Traugott的模块并自行修改 - 使其与subprocess
模块一起使用并不是太多工作。
这种方法比其他解决方案(例如基于SWIG
的解决方案或需要使用MinGW
/ MSYS
构建的解决方案)更少痛苦,我已经考虑并进行了实验。我对使用其他语言编写的系统使用了相同的(gpg.exe
/ iconv.dll
)方法,例如C#
,同样无痛苦的结果。
P.S。它适用于Python 2.4以及Python 2.5及更高版本。未经其他版本测试,但我没有预见到任何问题。
答案 1 :(得分:7)
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)
虽然问题很老。我希望这有助于未来的用户。
答案 2 :(得分:6)
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
答案 3 :(得分:3)
PyMe声称完全兼容Python 2.4,我引用:
PyMe的最新版本(截至此版本 写作)是v0.8.0。它的二进制 编译Debian的发行版 SWIG v1.3.33和GCC v4.2.3 for GPGME v1.1.6和Python v2.3.5, v2.4.4和v2.5.2(提供于 当时“不稳定”的分布)。 它的Windows二进制发行版 是用SWIG v1.3.29和。编译的 适用于GPGME v1.1.6和Python的MinGW v4.1 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的标准输出作为解密的明文。
答案 4 :(得分:3)
M2Crypto有PGP模块,但我实际上从未尝试过使用它。如果您尝试它并且它有效,请告诉我(我是当前的M2Crypto维护者)。一些链接:
更新:PGP模块不提供生成密钥的方法,但可能会使用较低级RSA,DSA等模块创建。我不知道PGP内部,所以你必须挖掘细节。另外,如果你知道如何使用openssl命令行命令生成这些命令,那么将它转换为M2Crypto调用应该相当容易。
答案 5 :(得分:3)
正如其他人所说,PyMe是这方面的规范解决方案,因为它基于GpgME,它是GnuPG生态系统的一部分。
对于Windows,我强烈建议您使用Gpg4win作为GnuPG发行版,原因有两个:
它基于GnuPG 2,其中包括gpg2.exe
,它可以(最后,我可以添加:)按需启动gpg-agent.exe
(gpg v1.x不能)
其次,它是GnuPG开发人员唯一正式构建的Windows。例如。它完全是从Linux到Windows的交叉编译,所以没有使用大量的非自由软件来准备它(对于安全套件非常重要:)。
答案 6 :(得分:0)
仅使用导出的公共密钥文件签名而不使用密钥环。
使用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快:我邀请您进行测试在您的环境中)。