PythonでPGPを行う方法(鍵の生成、暗号化・復号化)

Windowsユーザーにインストーラーで配布するプログラムをPythonで作っています。

このプログラムは、ユーザの公開鍵で暗号化されたファイルを毎日ダウンロードし、それを復号化する必要があります。

そこで、PGPの公開鍵と秘密鍵を生成し、公開鍵で暗号化されたファイルを復号化することができるPythonライブラリを探す必要があります。

これはpyCryptoが行うことでしょうか(ドキュメントは曖昧です)? 他の純粋なPythonライブラリはありますか? どの言語でも使えるスタンドアロンのコマンドラインツールはどうでしょうか?

私がこれまでに見たのはGNUPGだけでしたが、Windowsにインストールするとレジストリに何かをして、あらゆるところにDLLを投げます。そして、ユーザーがすでにこれをインストールしているかどうか、既存のキーリングをどのようにバックアップするか、などを心配しなければなりません。 私はむしろ、Pythonのライブラリやコマンドラインツールを持っていて、自分でキーを管理したいのです。

更新:pyMEは動くかもしれませんが、私が使わなければならないPython 2.4と互換性がないようです。

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)

PyMeは、Python 2.4との完全な互換性を謳っていますね。

PyMeの最新バージョン(この記事を書いている時点)はv0.8.0です。 最新バージョンはv0.8.0です。そのバイナリ Debian 用にコンパイルされたバイナリです。 SWIG v1.3.33 と GCC v4.2.3 でコンパイルされました。 GPGME v1.1.6 と Python v2.3.5 でコンパイルされています。 GPGME v1.1.6 と Python v2.3.5, v2.4.4, v2.5.2 (で提供されます)。

'unstable'distribution で提供)。 Windows 用のバイナリ配布は SWIG v1.3.29でコンパイルされています。 GPGME v1.1.6 と Python 用の MinGW v4.1 でコンパイルされています。 というバイナリでコンパイルされています。 v2.4.2でもインストールでき、問題なく動きます。 well)。

というのは、Python 2.4と互換性がないようなのです。

そして、GPGME上の半Pythonic (SWIGd) ラッパーとして存在します -- これは、基本的に仕事をするCライブラリがある場合に、Python拡張を開発する一般的な方法です。

PyPgpはもっとシンプルなアプローチで、単一のシンプルなPythonスクリプトになっています。例えば、復号はただ

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の代わりにsubprocessを使用するなど)。しかし、PGPがインストールされていないと、PyPgpは何もできません;-)。

解説 (2)

M2CryptoにはPGPモジュールがありますが、実は私は使ったことがありません。もし、使ってみてうまくいったら教えてください(私は現在のM2Cryptoのメンテナです)。いくつかリンクを貼っておきます。

  • モジュールソース][2
  • [デモスクリプト][3]
  • ユニットテスト][4

**PGPモジュールは鍵を生成する方法を提供していませんが、おそらく下位のRSADSAなどのモジュールで生成することができます。私はPGPの内部を知らないので、詳しくは調べてみてください。また、opensslのコマンドラインコマンドを使用してこれらを生成する方法を知っていれば、それをM2Cryptoの呼び出しに変換するのはそれなりに簡単なはずです。

解説 (2)