2012-05-08 2 views
8

В настоящее время я пытаюсь добавить поддержку подписи PGP в my small e-mail sending script (в которой используются модули Python 3.x и python-gnupg).PGP-подписывание многопользовательских писем с Python

Код, который подписывает сообщение является:

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!') 

(Здесь basemsg имеет email.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 (multipart/alternative или multipart/mixed).

Вручную проверять подпись на соответствующей части текста, но Evolution и Mutt сообщают, что подпись плохая.

Может ли кто-нибудь указать мне на мою ошибку?

ответ

5

Проблема в том, что модуль email.generator Python не добавляет новую строку перед частью подписи. Я сообщил, что вверх по течению как http://bugs.python.org/issue14983.

+0

Как вы это исправили? Есть ли место, чтобы легко добавить новую строку, или вам нужно было обезопасить email.generator? У меня такая же проблема. – micah

+0

@MicahLee Я не нашел никакого способа, кроме (обезьяны), исправления 'email.generator'. –

2

Что такое MIME-структура basemsg? Похоже, что в нем слишком много вложенных частей. Если вы экспортируете подписанное сообщение, например. Эволюция, вы увидите, что она состоит всего из двух частей: тела и подписи.

Вот пример, который генерирует сообщение на stdout, которое может быть прочитано, и подпись подтверждена как для mutt(), так и для 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'] = "[email protected]" 
    msg['To'] = "[email protected]" 
    print(msg.as_string(unixfrom=True)) # or send 
else: 
    print('Warning: failed to sign the message!') 

Обратите внимание, что здесь, я предполагаю, что в брелока с кодовой фразой, но вам не нужно это.

+0

Мой вопрос был о том, как подписать ** multipart ** e-mails. В вашем случае 'basemsg' - это простое сообщение MIMEText, а не многостраничное сообщение. Я нашел корень моей проблемы - это происходит потому, что 'email.generator' в Python не добавляет новую строку после конечной границы. Я не совсем уверен в этом; когда я стану уверен, что опубликую ответ, описывающий, как это исправить. –

+0

Дмитрий Шачнев: Ах, я не очень внимательно смотрел. Надеюсь, что ошибка скоро исправится! –

Смежные вопросы