PHPMailer DKIM签名异常咨询:复杂邮件签名验证失败
PHPMailer DKIM签名异常问题解析与解决
PHPMailer的DKIM功能本身是可靠的,你遇到的‘body was altered’错误,核心原因是DKIM参数设置的时机不对。
问题根源
DKIM签名是基于邮件最终的MIME结构和内容计算哈希值的。如果先构建邮件内容(比如设置Body+AltBody、调用msgHTML、添加附件),再配置DKIM参数,PHPMailer会提前生成签名,后续对邮件内容的修改会让实际发送的内容和签名时的内容不一致,最终触发篡改提示。
正确的代码示例
1. 带AltBody的HTML邮件
require 'PHPMailer/src/PHPMailer.php'; require 'PHPMailer/src/SMTP.php'; require 'PHPMailer/src/Exception.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; $mail = new PHPMailer(true); try { // 先配置DKIM参数,这一步必须在设置邮件内容之前! $mail->DKIM_domain = "domain.com"; $mail->DKIM_private = "/home/path/to/private.key"; $mail->DKIM_selector = "your_selector"; // 对应DNS里的DKIM记录前缀 $mail->DKIM_passphrase = "your_passphrase"; // 私钥无密码则留空 $mail->DKIM_identity = $mail->From; // 一般设为发件人邮箱 // 配置SMTP和邮件基础信息 $mail->isSMTP(); $mail->Host = 'smtp.yourserver.com'; $mail->SMTPAuth = true; $mail->Username = 'your_email@domain.com'; $mail->Password = 'your_smtp_password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 设置发件人、收件人、主题 $mail->setFrom('your_email@domain.com', 'Your Name'); $mail->addAddress('recipient@example.com', 'Recipient Name'); $mail->Subject = 'Test DKIM with AltBody'; // 最后设置邮件正文(HTML+文本替代内容) $mail->isHTML(true); $html = '<h1>HTML Body</h1><p>This is the HTML content.</p>'; $text = 'Plain text alternative body'; $mail->Body = $html; $mail->AltBody = $text; // 发送邮件 $mail->send(); echo 'Message has been sent'; } catch (Exception $e) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; }
2. 使用msgHTML(含内嵌图片)的邮件
require 'PHPMailer/src/PHPMailer.php'; require 'PHPMailer/src/SMTP.php'; require 'PHPMailer/src/Exception.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; $mail = new PHPMailer(true); try { // 优先配置DKIM参数 $mail->DKIM_domain = "domain.com"; $mail->DKIM_private = "/home/path/to/private.key"; $mail->DKIM_selector = "your_selector"; $mail->DKIM_passphrase = "your_passphrase"; $mail->DKIM_identity = $mail->From; // SMTP配置 $mail->isSMTP(); $mail->Host = 'smtp.yourserver.com'; $mail->SMTPAuth = true; $mail->Username = 'your_email@domain.com'; $mail->Password = 'your_smtp_password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 发件人、收件人、主题 $mail->setFrom('your_email@domain.com', 'Your Name'); $mail->addAddress('recipient@example.com', 'Recipient Name'); $mail->Subject = 'Test DKIM with msgHTML and inline images'; // 使用msgHTML,第二个参数是HTML文件所在目录(用于解析内嵌图片路径) $html = '<h1>HTML with Image</h1><p>See this image: <img src="logo.png"></p>'; $mail->msgHTML($html, __DIR__); // __DIR__表示当前脚本所在目录 // 发送邮件 $mail->send(); echo 'Message has been sent'; } catch (Exception $e) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; }
额外排查要点
- 确保DKIM私钥文件权限正确,PHP进程能读取该文件
- 核对DNS中的DKIM公钥记录:
your_selector._domainkey.domain.com的TXT记录值要和私钥对应 - 不要在设置DKIM参数后,再修改任何邮件内容(包括添加附件、调整编码、修改主题等)
内容的提问来源于stack exchange,提问作者Eric Moreau
相关产品推荐
相关产品推荐

