Ручная подпись электронной почты с помощью DKIM в Python

Я новичок в Python и пытаюсь создать сценарий отправки электронной почты через соединение через сокет, но, похоже, не могу подписать его с помощью библиотеки dkimpy. Я попробовал пару примеров в Интернете, но все они возвращали одну и ту же ошибку при запуске dkim.sign:

File "C:\Python34\lib\re.py", line 196, in split return _compile(pattern,flags).split(string, maxsplit)
TypeError: expected string or buffer

Насколько я могу судить, первая переменная в функции dkim.sign должна быть строкой, поэтому я попробовал readlines() и даже .as_string() просто для уверенности. Я проверил сообщение, и оно похоже на RFC822. Но я еще раз проверю, если кто-то думает, что это может быть проблемой. Без dkim.sign он работает отлично (минус любая безопасность, такая как SPF/DKIM)

Это фрагмент кода, который я использую:

f=open('mail.htm','r') 
text=MIMEText(f.read(),'html') 
headers = Parser().parse(open('mail.htm', 'r')) 
sender=headers['From'] 
receiver=headers['To'] 
subj=headers['Subject'] 
f.close() 
private_key = open('default.pem').read() 
headers = ['To', 'From', 'Subject'] 
sig = dkim.sign(text, 'default', '<mydomain.here>', private_key, include_headers=headers)

Проанализированные заголовки также используются в качестве входных данных для сценария отправки сокета. У меня есть ключ dkim для тестов, но я не думаю, что он доходит даже до этого момента.

Любое понимание?

РЕДАКТИРОВАТЬ: Хорошо, я только что попытался проанализировать строку (вместо того, чтобы подписывать ее) с помощью dkim.rfc822_parse из dkimpy lib, и я получаю следующую ошибку:

return _compile(pattern, flags).split(string, maxsplit)
TypeError: can't use a bytes pattern on a string-like object

Я читаю эту запись или мне кажется, что код ожидает строку, но шаблон в байтах?

ИСПРАВЛЕНО: Как ни странно, я не подумал проверить приватный ключ. Я вручную создал ключ в Win, поэтому без моего ведома Windows добавила невидимый символ разрыва строки, который даже vim или nano не могли видеть. После удаления с помощью MCEdit программа заработала без сбоев. Спасибо за помощь :)


person alex.b    schedule 03.04.2014    source источник


Ответы (2)


если я правильно помню, dkim.sign ожидает полный источник сообщения в качестве параметра, но вы передаете объект MIMEText.

попробуйте вместо этого передать text.as_string()

sig = dkim.sign(text.as_string(), .... )
person Gryphius    schedule 03.04.2014
comment
Кажется, это изменило ошибку на: не может использовать шаблон байтов для строкового объекта - person alex.b; 03.04.2014
comment
о, это похоже на проблему, специфичную для python3 (я еще не переключился на python 3, так что это простое предположение) - работает ли это, если вместо этого вы используете text.as_bytes()? - person Gryphius; 03.04.2014
comment
Да, это python 3. Никогда не думал попробовать это ... но по какой-то причине результат тот же. Но указанная библиотека и функция отличаются. с as_text ошибка находится в .split(string, maxsplit), а as_bytes возвращает ошибку в .search(string) (оба в re.py) - person alex.b; 03.04.2014
comment
Используйте decode() для преобразования bytes в str, например. b'test'.decode() ... Вы можете использовать encode() для преобразования str в bytes. - person Martin Tournoij; 03.04.2014
comment
кодирование в байты, кажется, работает для синтаксического анализатора rfc822, но не для функции sig... так что я предполагаю, что ошибка где-то еще... но это полностью противоречит моему пониманию - person alex.b; 03.04.2014
comment
Что делать дальше с переменной sig? - person Rui Martins; 06.04.2016
comment
Вы делаете это: msg['DKIM-Signature'] = sign[15:] ? - person Rui Martins; 06.04.2016

python3 обеспечивает сильную разницу между обработкой байтов и строк.

самый простой способ избежать преобразования при использовании модуля dkim — это оставаться в байтах, вот что я использую:

from email.parser import BytesParser
import dkim

mail = BytesParser().parse (open('mail.eml', 'rb'))

print(dkim.verify( mail.as_bytes () ) )))

"rb" предназначен для открытия файла в байтовом режиме.

Попробуйте.

person M'Fu    schedule 23.02.2019