2009-06-19 174 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) 

雖然問題很老。我希望這有助於未來的用戶。