10

現在、私の小さな電子メール送信スクリプト(Python 3.x とpython-gnupgモジュールを使用)に PGP 署名サポートを追加しようとしています。

メッセージに署名するコードは次のとおりです。

gpg = gnupg.GPG()
basetext = basemsg.as_string().replace('\n', '\r\n')
signature = str(gpg.sign(basetext, detach=True))
if signature:
    signmsg = messageFromSignature(signature)
    msg = MIMEMultipart(_subtype="signed", micalg="pgp-sha1",
    protocol="application/pgp-signature")
    msg.attach(basemsg)
    msg.attach(signmsg)
else:
    print('Warning: failed to sign the message!')

(こちらbasemsgemail.message.Messageタイプです。)

そしてmessageFromSignature機能は次のとおりです。

def messageFromSignature(signature):
    message = Message()
    message['Content-Type'] = 'application/pgp-signature; name="signature.asc"'
    message['Content-Description'] = 'OpenPGP digital signature'
    message.set_payload(signature)
    return message

次に、必要なすべてのヘッダーをメッセージ ( msg) に追加して送信します。

これは非マルチパート メッセージではうまく機能しますが、basemsgがマルチパート (multipart/alternativeまたはmultipart/mixed) の場合は失敗します。

対応するテキストに対して署名を手動で検証することはできますが、Evolution と Mutt は署名が悪いと報告しています。

誰かが私の間違いを指摘してもらえますか?

4

3 に答える 3

5

問題は、Pythonのemail.generatorモジュールが署名部分の前に改行を追加しないことです。その上流をhttp://bugs.python.org/issue14983として報告しました。

(このバグは2014年にPython2.7および3.3以降で修正されました)

于 2012-06-08T08:31:01.483 に答える
3

の実際の MIME 構造はbasemsg何ですか? ネストされたパーツが多すぎるようです。Evolution などから署名付きメッセージをエクスポートすると、本文と署名の 2 つの部分しかないことがわかります。

これは stdout で読み取り可能なメッセージを生成し、mutt ( mutt -f test.mbox) と Evolution (File -> Import) の両方で署名を検証する例です。

import gnupg
from email.message import Message
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

body = """
This is the original message text.

:)
"""

gpg_passphrase = "xxxx"

basemsg = MIMEText(body)

def messageFromSignature(signature):
    message = Message()
    message['Content-Type'] = 'application/pgp-signature; name="signature.asc"'
    message['Content-Description'] = 'OpenPGP digital signature'
    message.set_payload(signature)
    return message

gpg = gnupg.GPG()
basetext = basemsg.as_string().replace('\n', '\r\n')
signature = str(gpg.sign(basetext, detach=True, passphrase=gpg_passphrase))
if signature:
    signmsg = messageFromSignature(signature)
    msg = MIMEMultipart(_subtype="signed", micalg="pgp-sha1",
    protocol="application/pgp-signature")
    msg.attach(basemsg)
    msg.attach(signmsg)
    msg['Subject'] = "Test message"
    msg['From'] = "sender@example.com"
    msg['To'] = "recipient@example.com"
    print(msg.as_string(unixfrom=True)) # or send
else:
    print('Warning: failed to sign the message!')

ここでは、パスフレーズ付きのキーリングを想定していますが、必要ない場合もあります。

于 2012-05-31T09:15:03.450 に答える