DKIM 金鑰怎麼查是 1024 還是 2048 位元?從郵件標頭到 selector 輪替
本文目錄
要查目前寄信實際用的 DKIM 金鑰,先寄一封測試信到能查看原始郵件的收件端。從 DKIM-Signature 讀出簽章網域 d= 和選擇器 s=,用這兩個值組出 DNS 記錄名稱。直接猜 google 或 default 可能查到舊記錄;同一個網域也可能由多個寄信平台各自簽章。
RFC 8301要求 RSA DKIM 簽署者至少使用 1024 位元,建議使用 2048 位元以上。近期 DeepMind 兩份工作論文,一份在具特定簽署查詢條件的 1024 位元實驗重現中,使用約原先 1/3.5 的 CPU 時間;另一份估算有預計算時,大量分解同長度整數的邊際成本。這些結果沒有示範對一般 DKIM 部署的偽造,也沒有改變 RFC 的門檻。實務上可以用這個機會盤點仍在發信的 1024 位元金鑰。
從原始郵件查金鑰長度
如果實際標頭顯示 d=example.com; s=mail2026; a=rsa-sha256,要查的名稱就是 mail2026._domainkey.example.com。以下命令需要 Python 3、dig 和 OpenSSL;將範例的兩個值換成自己的簽章欄位。程式只查公開 DNS 和解析公開金鑰。
import base64import shleximport subprocess
domain, selector = "example.com", "mail2026"name = f"{selector}._domainkey.{domain.rstrip('.')}."result = subprocess.check_output(["dig", "+short", "TXT", name], text=True)records = [line for line in result.splitlines() if line.startswith('"')]if len(records) != 1: raise SystemExit(f"{name}: expected exactly one TXT record, got {len(records)}")
# dig 在同一行列出一筆 TXT 的多個字串片段。record = "".join(shlex.split(records[0]))tags = dict( (key.strip(), value.strip()) for key, value in (field.split("=", 1) for field in record.split(";") if "=" in field))if tags.get("k", "rsa").lower() != "rsa": raise SystemExit("This selector does not use RSA")if not tags.get("p"): raise SystemExit("Missing or revoked DKIM public key")
key = base64.b64decode("".join(tags["p"].split()), validate=True)public_key = subprocess.check_output( ["openssl", "pkey", "-pubin", "-inform", "DER", "-text", "-noout"], input=key,)print(name, public_key.decode().splitlines()[0])輸出中的 Public-Key: (2048 bit) 是 RSA 金鑰長度。TXT 記錄可由多個字串構成,RFC 6376要求查詢端把同一筆記錄的片段接起來,中間不補空格。DNS 控制台應把服務商給的長金鑰存成一筆 TXT;有些介面會替你拆片,請以 dig 查到的結果確認。遇到零筆先核對 d=、s=、DNS 委派和查詢的解析器;多筆則先檢查是不是誤把同一把金鑰分成幾筆 TXT。若服務商用 CNAME 委派 selector,查最終目標的 TXT,並由服務商管理金鑰。
新 selector 先可查,再切換寄信端
若寄信平台支援獨立準備及啟用金鑰,先產生新的 2048 位元金鑰和未使用的 selector。發布新 DNS 記錄,確認權威 DNS 以及你使用的遞迴解析器都能查到正確的公開金鑰,再讓寄信端使用新 selector。若採用 Google Workspace,依 Google 管理員文件產生記錄、發布並啟用驗證;先核對該平台是否允許分階段切換,若介面告知產生新金鑰會中斷簽署,就安排維護時段。
切換後,從每個實際寄信來源各寄一封新信,核對新 s=、預期的 d=,以及可信收件端加上的 Authentication-Results: ... dkim=pass 是否對應該簽章。收件端可能同時顯示其他簽章的通過結果;例如電子報和交易郵件共用寄件網域,仍要各自驗收。
正常輪替時,舊 selector 要留到既有郵件可能仍在寄信佇列或傳送中的時段過後,再依服務商的做法移除;若已確認舊私鑰外洩,改用事件應變流程決定何時撤銷。DNS 有新金鑰、信件確實用新金鑰簽署、收件端驗證成功,是三個不同的檢查結果。
參考資料: