[英]How to encrypt and decrypt .csv file to .csv.pgp using python script
[英]How to do PGP in Python (generate keys, encrypt/decrypt)
我正在用 Python 制作一个程序,通过安装程序分发给 Windows 用户。
该程序需要能够每天下载使用用户公钥加密的文件,然后对其进行解密。
所以我需要找到一个 Python 库,它可以让我生成公共和私人 PGP 密钥,并解密用公共密钥加密的文件。
这是 pyCrypto 会做的事情吗(文档模糊不清)? 还有其他纯 Python 库吗? 任何语言的独立命令行工具怎么样?
到目前为止我所看到的只是 GNUPG,但是在 Windows 上安装它会对注册表做一些事情并在任何地方抛出 dll,然后我不得不担心用户是否已经安装了它,如何备份他们现有的密钥环等。我宁愿只需有一个 python 库或命令行工具并自己管理密钥。
更新:pyME 可能有效,但它似乎与我必须使用的 Python 2.4 不兼容。
您不需要PyCrypto
或PyMe
,尽管这些软件包可能是好的 - 在 Windows 下构建时会遇到各种问题。 相反,为什么不避开兔子洞并做我所做的呢? 使用gnupg 1.4.9
。 您不需要在最终用户机器上进行完整安装 - 只gpg.exe
发行版中的gpg.exe
和iconv.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
构建的解决方案)要少得多,我考虑并尝试了这些方法。 我对用其他语言(例如C#
)编写的系统使用了相同的( gpg.exe
/ iconv.dll
)方法,结果同样gpg.exe
。
PS 它适用于 Python 2.4 以及 Python 2.5 及更高版本。 没有用其他版本测试过,但我不认为有任何问题。
经过大量挖掘,我找到了一个对我有用的软件包。 虽然据说支持生成key,但是我没有测试。 但是我确实设法解密了使用 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)
虽然这个问题很老了。 我希望这对未来的用户有所帮助。
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
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 不会做任何事情;-)。
正如其他人所指出的,PyMe 是对此的规范解决方案,因为它基于 GpgME,它是 GnuPG 生态系统的一部分。
对于 Windows,我强烈建议使用Gpg4win作为 GnuPG 发行版,原因有二:
它基于 GnuPG 2,其中包括gpg2.exe
,它可以(最后,我可能会添加:)按需启动gpg-agent.exe
(gpg v1.x 不能)。
其次,它是 GnuPG 开发人员唯一的官方 Windows 版本。 例如,它完全从 Linux 交叉编译到 Windows,因此在准备它时没有使用任何非自由软件(对于安全套件非常重要:)。
仅使用导出的公钥文件进行签名,而无需密钥环。
使用 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 快:我将邀请您在您的环境中进行测试)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.