2012-05-08 18 views
8

Actualmente estoy tratando de agregar soporte de firma de PGP al my small e-mail sending script (que usa el módulo Python 3.xy el módulo python-gnupg).PGP-firmando correos electrónicos de varias partes con Python

El código que firma el mensaje es:

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

(Aquí basemsg es de email.message.Message tipo.)

Y messageFromSignature función es:

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 

Luego añadir todas las cabeceras necesarias al mensaje (msg) y enviarlo.

Esto funciona bien para mensajes no multiparte, pero falla cuando basemsg es multiparte (multipart/alternative o multipart/mixed).

Verificando manualmente la firma con respecto a la pieza de texto correspondiente funciona, pero Evolution y Mutt informan que la firma es incorrecta.

¿Alguien puede señalarme mi error?

Respuesta

5

El problema es que el módulo email.generator de Python no agrega una nueva línea antes de la parte de la firma. He informado que upstream como http://bugs.python.org/issue14983.

+0

¿Cómo terminaste arreglando? ¿Hay algún lugar para agregar una nueva línea fácilmente o tienes que enviar un correo electrónico a monkey.generator? Estoy teniendo el mismo problema. – micah

+0

@MicahLee No he encontrado ninguna forma además de parche (mono) 'email.generator'. –

2

¿Cuál es en realidad la estructura MIME de basemsg? Parece que tiene demasiadas partes anidadas. Si exporta un mensaje firmado de, por ejemplo, Evolución, verás que tiene solo dos partes: el cuerpo y la firma.

Aquí hay un ejemplo que genera un mensaje en stdout que se puede leer y la firma se puede verificar tanto en mutt (mutt -f test.mbox) como en 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!') 

Tenga en cuenta que aquí, estoy asumiendo un llavero con una frase de contraseña, pero puede que no necesite eso.

+0

Mi pregunta era sobre cómo firmar correos electrónicos ** multipart **. En su caso, 'basemsg' es un simple mensaje MIMEText, no un mensaje multiparte. He encontrado la raíz de mi problema: sucede porque 'email.generator' en Python no agrega una nueva línea después del límite final. No estoy muy seguro de eso; cuando me asegure de publicar una respuesta que describa cómo solucionarlo. –

+0

Dmitry Shachnev: Ah, no estaba mirando lo suficiente. Espero que el error se resuelva pronto! –

Cuestiones relacionadas