Defaults.Exposed

Defaults.Exposed修復Guides

DKIM“Body Hash Did Not Verify”——是什麼改動了你的郵件,以及怎麼修(2026)

發布於 2026-07-08

資料截至 2026-06-29 · 方法論 v7。 基於 261 百萬個已評分網域的彙總普查資料。參見我們如何評分

“Body hash did not verify”意味著郵件离開你時 DKIM 簽名是有效的——之後有東西改寫了郵件正文。簽名沒壞;是郵件在傳輸途中被修改了。根據 Defaults.Exposed 對 261,086,232 個網域的普查(2026-06-29),只有 3.87% 的網域——10,092,481 個——凑齊了 SPF-DKIM-DMARC 完整三件套。

修復是一場追查,然後一個決定。找到那個改動你郵件的節點——追加免責宣告的閘道、改寫連結的安全設備、加頁脚的郵件列表。然後按順序三選一:在那個節點之後簽名、停止改動,或讓簽名容忍它。

“body hash did not verify”到底是什麼意思?

DKIM 簽名(RFC 6376)攜帶兩個雜湊:bh=,簽名時郵件正文的雜湊;b=,對標头加該正文雜湊的簽名。驗證方用收到的郵件重新計算正文雜湊;如果和 bh= 對不上,驗證就此打住,留下那串人人都會贴進搜索框的文字——一條類似這樣的接收方標头:

Authentication-Results: …; dkim=fail (body hash did not verify)

這是 Microsoft 文件中的原因字串;Gmail 常把同一診斷顯示為 dkim=neutral (body hash did not verify)。无論哪種,這個裁決都把問題範圍大大收窄了。你的 DNS 金鑰、選擇器、簽名設定全都沒問題。密碼學尽了職責:正文在簽名與驗證之間變了——追加一行、改寫一個 URL、重新編碼一個字元就足夠。(不同的資訊——signature did not verifyno key for signature——意味著不同的故障;從“DKIM signature not valid”看起。)它之所以紧迫,是因為失敗的簽名无法給 DMARC 一個對齊的通過:除非同一封郵件的 SPF 以對齊方式通過,否則郵件就直接 DMARC 失敗。

是什麼改動了你的郵件?惯犯名單

投遞路径上有東西在簽名封印之後編輯了正文。實践中就是這四種之一:

誰改的改了什麼典型特徵
出站閘道 / smart host(Exchange 傳輸規則、Mimecast、Proofpoint、Barracuda……)在郵件伺服器已經簽名之後追加法律免責宣告、營銷頁脚或“EXTERNAL:”横幅走該路由的郵件全部失敗;繞過閘道的直發通過
安全設備 / 連結保護把 URL 改寫成掃描跳轉,加追踪包装只有含連結的郵件失敗
郵件列表(Google Groups、Mailman……)加主題標簽和列表頁脚,有時重排正文只有經列表發出的郵件失敗
轉發方 / 重新編碼 MIME 的中繼轉換字元集、重新折行——人眼看不見,對雜湊是致命的失敗集中在某一個收件人或轉發位址

先查加粗那一行——郵件伺服器簽名,邊緣設備編輯,每封郵件出門時帶著一個只真實存在了三十毫秒的簽名。

怎麼找到正在改動我郵件的那個節點?

鑒別診斷——拿一條能通的路径和失敗的路径做對比:

  1. 向你控制的一個大型接收方郵箱(Gmail 就很合適)發一封直發測試郵件,尽量繞開你的出站鏈路。
  2. 沿失敗路径發第二封——經閘道、經列表、發往受影響收件人的網域。
  3. 對比兩份完整標头裡的 Authentication-Results 行。直發 dkim=pass,失敗路径 dkim=fail(或 dkim=neutral)且帶 body hash did not verify:改動者就住在這兩條路由的差集裡。
  4. 看收到的正文:有你沒打過的免責宣告、横幅或頁脚?連結被改寫到某個掃描網域?那就是你的節點,名字都有了——Received: 鏈還會顯示哪個中繼只出現在失敗路径上。

你的 DMARC 彙總報告在更大尺度上讲著同一個故事:某個來源持續報告 DKIM 失敗而 SPF 通過,通常就是你自己路由上的傳輸途中修改,不是攻擊者。

怎麼修?

  1. 動手之前先在 defaults.exposed 執行免費掃描。 它確認你發布的 DKIM 金鑰和 DMARC 政策沒有問題,這樣你調試的就是那一個真問題——改動本身——而不是在 DNS 裡追鬼影。修復 DKIM 頁面覆蓋了記錄側的檢查。
  2. 在改動節點之後簽名。 架構上正確的修法:把 DKIM 簽名移到接触郵件的最外層設備。用 Exchange 加閘道的機構應當在閘道簽名(Mimecast、Proofpoint 及同類都支援),並停用上游簽名。如果 Google Workspace 或 Microsoft 365 是你的最後一跳,就在那裡簽名,並且不讓任何東西在它之後編輯郵件——見在 Google Workspace 設定 DKIMMicrosoft 365
  3. 或者停止改動。 把編輯從傳輸路径上拿走:免責宣告放進客戶端簽名或模板,而不是傳輸規則;“EXTERNAL:”横幅只限定到入站郵件(把自家出站郵件標成外部,是錯上加錯的設定);已驗證的出站郵件豁免連結改寫。
  4. 使用 relaxed/relaxed 規範化(c=relaxed/relaxed)。 simple 正文規範化在一行被重新折行時就失敗;relaxed 容忍空白和行尾變化。對局限要誠實:relaxed 原谅的是排版,從不原谅內容——追加的頁脚照樣失敗,也理應失敗。
  5. 重測兩條路径,然後重新掃描。 兩條路由現在都應顯示 dkim=passd= 是你的網域,掃描報告也應干干淨淨。

我該不該用 l= 標簽讓 DKIM 忽略追加的內容?

不該——並且要警惕任何建議這麼做的指南。l= 標簽只對正文的前 N 個字節做雜湊,於是追加的頁脚不再破壞簽名。它的“有效”是靠讓你郵件的結尾不被簽名:任何人拿到一封合法簽名的郵件,都能在後面追加任意內容,而你的有效簽名對結果照樣驗證通過。這是披著修復外衣的偽造漏洞——實際濫用已被演示過,一些接收方正因如此對 l= 扣分或直接无視。解決改動本身;別把你的郵件簽一半。

那郵件列表呢——能修嗎?

多半不能——知道這一點能給你省下几周。會加主題標簽或頁脚的列表,破壞你的正文雜湊是設計使然,而列表不歸你管。有兩件事幫得上忙:

轉發是相邻的情形——它必然破壞 SPF,但只是偶尔破壞 DKIM,這正是當正文幸存時,對齊的 DKIM 是你抗轉發的那條腿:見轉發的郵件 SPF 失敗——為什麼你修不了

完整配齊的網域這麼少,DKIM 為什麼還這麼容易壞?

因為 DKIM 是三件套裡脆弱的中間孩子:SPF 是一條静態 DNS 記錄,DMARC 是一份政策宣告,而 DKIM 必須活著走完旅程。根據 Defaults.Exposed 普查,只有 51.84% 的已評分網域在 DNS 中發布了可發現的 DKIM 金鑰,而在 261,086,232 個已評分網域中,只有 10,092,481 個——3.87%——同時具備 SPF、DKIM 和強制執行的 DMARC 政策(SPF 採用成熟度模型拆解了這架梯子)。把這個修復做對,是跻身那 3.87% 最難的一步。

常見問題

“body hash did not verify”是不是有人在冒充我的網域的迹象? 通常不是——偽造者一般根本造不出你的 DKIM 簽名,所以他們的郵件要麼沒有簽名,要麼顯示 no key。正文雜湊失敗意味著一封確實由你的基礎設施簽名的郵件事後被編輯了。先查你自己的閘道,再去假設攻擊者。

這些郵件的 SPF 是通過的——我還安全嗎? 眼下也許安全:DMARC 只需要一個對齊的通過。但只要有人轉發,SPF 的通過就蒸發了;而如果它沒有與你的 From 網域對齊,那它對 DMARC 從來就沒算過數。在只有 3.87% 的網域配齊三件套的情况下(2026-06-29 普查,261,086,232 個網域),“一條腿瘸著”是常態——也是可修復的那種。

換成 relaxed/relaxed 規範化能解決我的免責宣告問題嗎? 不能。Relaxed 只容忍空白和折行的變化。追加的免責宣告是內容變化,雜湊必須為此失敗——那是 DKIM 在正確工作。要麼移簽名點,要麼移免責宣告。

失敗只發生在某一個客戶的網域上。為什麼? 几乎可以肯定是他們那邊在修改入站郵件——某台安全設備在他們的驗證器執行之前改寫連結或蓋横幅,或者一次內部轉發重新編碼了正文。把本頁的診斷部分發給他們;修復在他們的閘道上,不在你的 DNS 裡。

把報告發給老板

如果你是在替客戶或雇主修這個問題,用證據收尾。改動節點修好之後,重新執行免費掃描,把評分報告轉發給企業負責人:帶日期、直白語言,DKIM 和 DMARC 的狀態一頁看清。這正是網路保險續保和下一份供應商問卷需要的凭證——證明公司發出的郵件,如今就是送達的那封郵件。

檢查你的網域 → · “DKIM signature not valid”指南 → · 修復 DKIM → · 我們如何評分 → · 僅使用彙總資料。資料在歐盟境內儲存和處理。