如何用Python验证邮件DKIM签名?需获取详细问题信息
使用Python的dkimpy验证DKIM签名并获取详细结果
首先安装dkimpy包:
pip install dkimpy
dkimpy的核心是dkim模块,通过它可以完成签名验证,并捕获不同类型的错误来定位具体问题。以下是具体实现步骤和代码示例:
基础验证(含错误详情)
dkimpy的verify函数接收字节格式的原始邮件内容,返回布尔值表示验证结果。同时,它会针对不同的失败场景抛出特定异常,我们可以通过捕获这些异常来获取详细问题信息:
import dkim # 读取原始邮件文件(确保是完整的RFC 5322格式字节流) with open("raw_email.eml", "rb") as f: raw_email = f.read() try: # 执行验证 is_valid = dkim.verify(raw_email) if is_valid: print("DKIM签名验证通过") else: print("DKIM签名验证失败(无具体异常,可能是签名匹配但策略不通过)") except dkim.SignatureNotFound: print("错误:邮件中未找到DKIM-Signature头部字段") except dkim.KeyNotFound: print("错误:无法从DNS获取对应域名的DKIM公钥(域名不存在或公钥记录缺失)") except dkim.InvalidSignature: print("错误:DKIM签名无效,可能是邮件内容被篡改、签名算法不匹配或过期") except dkim.DKIMException as e: print(f"DKIM验证过程中发生未知错误:{str(e)}")
处理多签名邮件并获取签名细节
部分邮件可能包含多个DKIM签名,你可以先提取所有签名,再逐个验证,同时获取签名的域名、选择器等信息:
import dkim with open("raw_email.eml", "rb") as f: raw_email = f.read() # 提取邮件中的所有DKIM签名 signatures = dkim.get_signatures(raw_email) for idx, sig in enumerate(signatures): print(f"\n=== 第{idx+1}个签名 ===") print(f"签名域名:{sig.domain}") print(f"选择器:{sig.selector}") print(f"签名算法:{sig.algorithm}") try: # 单独验证当前签名 is_valid = dkim.verify(raw_email, signature=sig) print(f"验证结果:{'通过' if is_valid else '失败'}") except dkim.DKIMException as e: print(f"验证错误:{str(e)}")
注意事项
- 运行环境需要能够正常访问DNS,因为验证过程需要查询域名的DKIM公钥记录
- 必须使用原始字节格式的邮件内容,不能是经过解析或修改后的文本
- 如果验证返回
False但未抛出异常,通常是签名格式合法但内容校验不通过
内容的提问来源于stack exchange,提问作者Azog
相关产品推荐
相关产品推荐

