在Python中手动用DKIM签名邮件

5 投票
2 回答
4097 浏览
提问于 2025-04-18 01:08

我刚开始学习Python,想通过socket通信来创建一个发送邮件的脚本,但在用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)

解析后的头部信息也被用作socket发送脚本的输入。我确实有一个用于测试的dkim密钥,但我觉得程序甚至没有到达那一步。

有没有什么见解?

编辑:好的,我刚刚尝试用dkimpy库中的dkim.rfc822_parse来解析字符串(而不是签名),结果出现了以下错误:

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

我这样理解对吗?看起来代码是期待一个字符串,但模式却是字节?

解决了:奇怪的是,我没有想到检查私钥。我是在Windows上手动创建的密钥,所以我不知道Windows添加了一个看不见的换行符,连vim或nano都看不出来。用MCEdit去掉后,程序就顺利运行了。感谢大家的帮助 :)

2 个回答

0

Python3 在处理字节和字符串时有很明显的区别。

我发现避免转换的最简单方法是保持使用字节,这里是我用的代码:

from email.parser import BytesParser
import dkim

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

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

这里的 "rb" 是用来以字节模式打开文件的。

试试看吧。

4

如果我没记错的话,dkim.sign 这个函数需要的是完整的消息内容作为参数,但你现在传入的是一个 MIMEText 对象。

试试用 text.as_string() 来替代吧。

sig = dkim.sign(text.as_string(), .... )

撰写回答