2009-06-19 175 views
26

我在Python做节目通过安装程序分发给Windows用户。如何做到在Python PGP(生成密钥,加密/解密)

程序需要能够每天与用户的公钥加密下载一个文件,然后将其解密。

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

这是不是pyCrypto会做(文件是含糊不清)?还有其他纯Python库吗?如何使用任何语言的独立命令行工具?

我到目前为止看到的只有GNUPG,但是在Windows上安装它可以在注册表中执行任何操作,并且会引发dll的无处不在,然后我不得不担心用户是否已经安装了该程序,如何备份其现有的密钥环等。我宁愿只是有一个python库或命令行工具,并自己管理密钥。

更新:pyme可能会工作,但它似乎不与我必须使用的Python 2.4兼容。

回答

24

你不需要PyCryptoPyMe,虽然这些软件包可能会很好 - 你会在Windows下建立各种问题。相反,为什么不避开兔子洞并做我所做的?使用gnupg 1.4.9。你并不需要做对最终用户的机器完全安装 - 只需gpg.exeiconv.dll从分布是足够的,你只需要在一些地方有他们在的路径,或使用一个全路径名从你的Python代码访问。需要对注册表的任何更改,一切(可执行文件和数据文件),如果你想被限制到一个文件夹。

有一个模块GPG.py最初由Andrew Kuchling编写,由Richard Jones改进并由Steve Traugott进一步改进。它的问世here,但是,是不是因为它使用os.fork()是不适合的Windows。虽然最初的PyCrypto一部分,它是完全独立的PyCrypto其他部分,只需要gpg.exe/iconv.dll才能工作

我有一个从Traugott的GPG.py派生的版本(gnupg.py),它使用subprocess模块。它在Windows下正常工作,我的目的至少 - 我用它来执行以下操作:

  • 密钥管理 - 代,上市,出口等。(收到来自外部源
  • 导入密钥如公钥来自合作伙伴公司)
  • 加密和解密数据
  • 签名和验证签名

我有这个模块是不理想的,现在来展示,因为它包含了这不应该是一些其他的东西疗法e - 这意味着我目前无法释放它。在某个时候,也许在接下来的几个星期里,我希望能够整理它,增加更多的单元测试(例如我没有任何单元测试用于标记/验证),并释放它(或者原始PyCrypto许可证或类似的商业友好许可证)。如果您不能等待,请使用Traugott的模块并自行修改 - 使其与subprocess模块一起工作并不是太多工作。

这种方法是很多比别人少痛苦(例如SWIG基于解决方案或解决方案,需要与MinGW/MSYS建筑),这是我考虑和尝试。对于用其他语言编写的系统,我已经使用了相同的(gpg.exe/iconv.dll)方法。 C#,同样无痛的结果。

P.S.它适用于Python 2.4以及Python 2.5及更高版本。未经其他版本测试,但我没有预见到任何问题。

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 

Futhermore,公钥/ 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 
+2

我看不到一种方法来生成密钥,或接受另一方的公钥来加密数据。有任何想法吗? – Greg 2009-06-25 17:27:49

+3

不,PyCrypto中的MODE_PGP是传统的实验性代码,可能永远不能正确工作。 (请参阅https://bugs.launchpad.net/pycrypto/+bug/996814)。不要使用它。无论如何,我们将很快从PyCrypto中删除它。 – dlitz 2012-05-09 00:13:39

+1

那么你有什么建议,@dlitz? – raylu 2013-07-17 22:50:55

2

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为V1.1.6 GPGME和Python V2.5.2编译(尽管相同的二进制安装得和 在V2.4.2工作正常的 井) 。

我不知道你为什么说“它似乎不与我必须使用的Python 2.4兼容” - 请详细说明?

是的它确实存在,作为一个半Python化(SWIGd)上GPGME包装 - 这是发展Python扩展,一旦你有一个C库,基本上没有工作的流行方式。

PyPgp有一个简单得多的方法 - 这就是为什么它是一个简单的Python脚本:基本上它只不过是对命令行PGP命令的“外壳”。例如,解密只是:

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不会做任何事情;-)。

+0

PyMe是这个问题:http://stackoverflow.com/questions/1030297/how-to-make-a-pyme-python-library-run-in-python-2-4-on-windows – Greg 2009-06-25 16:50:11

+0

是的,他们声称(特别是Windows)没有根据(在Windows中,只有扩展需要针对特定​​版本的Python进行编译,因此编译为2.5的编译器不适用于2.4)。所有你需要的是重新编译(这需要MSVC 6.0)。 – 2009-06-25 21:15:46

3

M2Crypto有PGP模块,但我却从未尝试过使用它。如果你尝试了它,并且它工作,请让我知道(我是当前的M2Crypto维护者)。有些链接:

更新:的PGP模块不提供的方法来生成密钥,但据推测这可能与较低水平RSA创建,DSA等模块。我不知道PGP的内部,所以你必须挖掘细节。另外,如果你知道如何产生这些使用OpenSSL的命令行命令,它应该是相当容易将其转换成M2Crypto调用。

2

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

对于Windows而言,我强烈建议使用Gpg4win作为GnuPG的分布,有两个原因:

它基于的GnuPG 2,其中,除其他事项外,包括gpg2.exe,它可以(最后,我想补充: )开始gpg-agent.exe按需(gpg v1.x不能)。

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

1

经过大量的挖掘,我找到了一个为我工作的包。虽然据说支持密钥的生成,但我没有对它进行测试。不过,我设法解密了使用GPG公钥加密的消息。这个软件包的优点是它不需要计算机上的GPG可执行文件,并且是基于Python的OpenPGP实现(而不是可执行文件的包装)。 我使用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) 

虽然问题很老。我希望这有助于未来的用户。