兩個訊息在郵件用戶端中可能看起來相同,但仍然會產生不同的結果 DKIM 正文哈希值。 DKIM在指定後驗證傳輸的表示形式 規範化,而不是讀者的解碼視圖。因此,當訊息僅在處理服務之後失敗時, MIME重建、內容傳輸轉換和邊界變更屬於調查的早期階段。
將外觀與表現分開
MIME訊息可以包含純文字、HTML、附件和巢狀的多部分結構。 RFC 2046 §5.1.1 將MIME部分標頭和邊界定界符放置在多部分主體內。將文字部分從 Quoted-printable 重新編碼為 Base64 可以保留使用者讀取的內容,同時變更呈現給DKIM的位元組。重新包裝編碼行也可以更改這些位元組。 寬鬆的規範化 是定義的空白轉換,而不是MIME解碼器或渲染內容的等效測試。
RFC 6376 §5.3 建議在簽章之前轉換為適當的MIME傳輸編碼,以減少傳輸轉換。它特別要求在傳輸之前發生變化的本地表示在簽名之前進行標準化。操作原理很簡單:在接收者希望看到的表格上簽名。
找到序列化更改
在簽署者輸出、可疑網關輸出和最終接收者處取得原始訊息。儲存原件,無需透過標準化行結尾的編輯器開啟和儲存它們。請注意收集方法,因為匯出工具本身可以更改表示形式。
比較外部訊息和每個相關MIME部分的 Content-Type 和 Content-Transfer-Encoding 欄位。檢查邊界字串、附件編碼、折疊線和字元集轉換。確定 h 中是否包含更改的外部標頭以及簽名主體內部是否出現更改的部分標頭。分別對待這兩個位置:外部標頭可能會導致簽章驗證失敗,而MIME部分標頭通常參與簽章驗證。 正文哈希.
完成編碼範例
說明性測試規範:在應用程式對訊息進行簽署之前,使用quoted-printable 準備包含非ASCII 字元的文字部分。下游服務對該部分進行解碼並將其序列化為 base64。顯示的句子保持不變,但規範化主體可能不同,原始簽名可能會失敗。僅使用受控內容執行此轉換並檢查實際位元組差異,而不是假設每個服務都執行此轉換。
建立一個小型測試集,其中包含純 ASCII 純文字、非 ASCII 文字、多部分 HTML 和一個小附件。透過直接控制路徑和生產等效處理路徑發送每個路徑。如果只有後者改變表示,則邊界比較會識別要研究的組件。如果兩者都失敗,請先檢查簽署者自己的序列化和規範化。
修復邊界
在簽章之前優先選擇最終的MIME構造和傳輸編碼選擇。如果安全服務必須重寫內容,請在最終序列化後安排授權簽章步驟。確認其自訂網域支援和所有權模型;不相關服務網域下的簽章可能會在不對齊的情況下透過DKIM DMARC 在下面 RFC 9989 §4.4.1.
請勿就地修復樣品並將其作為生產已修復的證據。修改後的樣本僅檢驗假設。更改負責的配置,發送新的受控訊息並捕獲其原始接收器結果。避免僅僅為了保留簽名而廣泛繞過內容檢查而不審查安全後果。
保留有用的事件記錄
記錄序列化內容分歧的第一個邊界、受影響的MIME欄位或部分、簽署者和 選擇器,以及每個測試變體的結果。保持測試訊息不含客戶資料。網關升級和附件處理更改後重新運行套件。已完成的修復解釋了舊表示失敗的原因,並表明新發出的郵件在完全受支援的路由中仍然存在。
比較具體的編碼表示
對於表示 é 的 UTF-8 位元組 C3 A9,帶引號的可列印表示為 =C3=A9; Base64 表示是 w6k=。使用適當的MIME標頭,兩者都會解碼為相同的字符,但編碼的字串不同。 RFC 2045 §6.7 和 RFC 2045 §6.8 定義編碼; RFC 6376 §3.7 需要在傳輸編碼之後和驗證期間解碼之前進行雜湊。這個孤立的表示範例不是完整的MIME訊息或執行的簽名測試。如果使用主體長度限制,請確定已變更的位元組是否在覆蓋範圍內,而不是假設每個部分都受到保護。