本文ハッシュが一致しない
メーリングリストが153バイトのフッターを追加しました。ヘッダーはproject.exampleの鍵でまだ検証できるため、偽造ではありません。
対処 本文を変更しないリスト、またはARC(RFC 8617)を使い、あとの受信サーバーに元の結果が見えるようにします。
body-hash-mismatchテーマ
ドメインのDKIMレコードを受信メールサーバーが見つけるのと同じ方法で確認するか、メールを貼り付けて署名をテストします:どのセレクターが応答するか、誰が署名しているか、各鍵がどれだけ強いか、DMARCとアラインしているか。
DNSにはセレクターの一覧を取得する機能がないため、メールプロバイダーが使う140個のセレクターを、selector._domainkey.にドメインを付けた名前で問い合わせます
上の欄にドメインを入力してください:チェッカーはメールプロバイダーが使う140個のセレクターを問い合わせ、見つかったすべての鍵を長さとプロバイダーとともに表示し、何も見つからなければ、そのとおりに伝えます。セレクターが分かっている場合はドメイン + セレクターを選ぶと、それが最初に確認されます。
手作業で確認するにはセレクターが必要です。DNSにはセレクターの一覧を取得する機能がないためです:dig +short TXT selector._domainkey.example.com、Windowsなら同じ名前でnslookup -type=TXT。セレクターは、どのメールのDKIM-Signatureにもあるs=の値です(RFC 6376 §3.6.2.1)。
digが表示するのはテキストだけで、その意味までは分かりません:鍵の長さを復元せず、プロバイダーのCNAMEをたどらず、待機用の枠と壊れた設定も区別しません。それを補うのが、このDKIMチェックです。
dig +short TXT selector._domainkey.example.comこの名前のすべてのTXT文字列を表示します。連結すると鍵を読み取れます。
digで分かること、分からないこと
$ dig +short TXT 20251104._domainkey.google.com 1
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQ…" "…k2A8ZfpQIDAQAB"2
$ dig +short TXT 20251104._domainkey.google.com | tr -d '" \n' | sed 's/.*p=//' | base64 -d | openssl pkey -pubin -inform DER -noout -text | head -1 3
Public-Key: (2048 bit)
$ dig +short TXT selector1._domainkey.microsoft.com 4
selector1-microsoft-com._domainkey.microsoft.onmicrosoft.com.
最初に1文で答えが表示されます。その下に、誰が署名しているかと鍵そのものが続きます:各タグを実際の文字位置で色分けし、鍵の長さをRFC 8301の基準で表示します。紺色の背景には確認したすべてのセレクターが表示されるため、何を試したかが分かります。
点数はありません:廃止された鍵やプロバイダーの空の待機用セレクターは正常で、「一般的なセレクターに見つからない」は「DKIMなし」を意味しません。

判定1文で、鍵がいくつあるか、何をすべきかを示します。署名者プロバイダーごとに1枚のカード。CNAMEまたは公開されているセレクターから判定します。各セレクターのチップから鍵を開けます。鍵各タグを文字位置ごとに色分けし、鍵の長さをRFC 8301の基準で示します。セレクター探索問い合わせた名前が応答するたびに点灯します:緑は鍵、黄は1024ビット、破線は待機用の枠です。DMARCアライメントこのドメインのd=を持つ鍵が、DMARCポリシーとアラインするかを示します。DKIM(DomainKeys Identified Mail)は、送信サーバーが各メッセージに付ける署名で、受信サーバーはドメインがDNSで公開している公開鍵で確認します(RFC 6376)。有効な署名は2つのことを証明します:d=のドメインが署名したこと、そして署名された部分がそれ以降変更されていないことです。
送信側は本文をハッシュしてbh=に入れ、選んだヘッダーとそのハッシュを秘密鍵で署名してb=に入れます。受信側はd=とs=を読み、s._domainkey.dの鍵を取得して、両方をやり直します。本文または署名されたヘッダーが1バイトでも変わると、検証は失敗します。
DKIMは、失敗したときにどうするかについては何も述べず、どのドメインでも署名できます。それを担うのがDMARCで、d=がFrom:ドメインと一致する有効な署名を求めます。
1通のメールを、送信側で署名し、受信側で確認する
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=dnsrobot-sample; h=from:from:to:subject:…; bh=fohb/a+auh1W9cUN…; b=fF0aMr3Uo+mbgG…
dnsrobot-sample._domainkey.example.com TXT?"v=DKIM1; k=rsa; p=MIIBIjANBgkq…"RSA 2048
送信されたままのメッセージ
dkim=pass header.d=example.com
途中でSubjectが書き換えられた同じメッセージ
dkim=fail (signature-mismatch)
セレクターは1つのDKIM鍵の名前です:署名のs=であり、鍵があるDNS名の最初のラベルでもあります(s1._domainkey.github.com)。ドメインはいくつでも持てます:プロバイダーごと、サーバーごと、年ごとに1つずつ(RFC 6376 §3.1)。
自分のセレクターを調べるには、ドメインが送信したメールを開いて元のメッセージを見ます:Gmailのその他(⋮) › メッセージのソースを表示にDKIM-Signatureが表示され、そのs=がセレクターです。または、上のメールを検証にメールを貼り付けてください。
多くのプロバイダーは固定の名前を使うため、探索で見つかります。Amazon SES、Postmark、SparkPost、HubSpotはアカウントごとに名前を生成するため、メールかプロバイダーの管理画面でしか分かりません。
署名から鍵まで、そしてプロバイダーが使う名前
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; s=s1; …
s1._domainkey.github.comCNAME s1.domainkey.u51742174.wl175.sendgrid.netRSA 2048
| Google Workspace | 管理者がプレフィックスを変更できる | |
|---|---|---|
| Microsoft 365 | selector1 · selector2 | テナントへのCNAME。1つが有効、1つが待機 |
| Twilio SendGrid | s1 · s2 | u<id>.wl<n>.sendgrid.netへのCNAME |
| Mailchimp | k2 · k3 | dkim2/dkim3.mcsv.netへのCNAME |
| Fastmail | fm1 · fm2 · fm3 | CNAMEが3つあり、一度に1つだけ使用 |
| Proton Mail | protonmail · 2 · 3 | domains.proton.chへのCNAME |
| Amazon SES | ランダムなトークン3つ | それぞれランダムな32文字:推測できない |
| Postmark | 20240101000000pm | 日付と「pm」:推測できない |
| SparkPost | scph + MMYY | scphと、鍵を作成した月 |
| HubSpot | hs1-<HubID> | アカウント番号 |
DKIMレコードは、セミコロンで区切ったタグ=値の組からなるTXTレコードで、必須なのは公開鍵のp=だけです。 v=DKIM1は省略可能ですが、ある場合は先頭に置く必要があります(RFC 6376 §3.6.1)。
k=は鍵の種類(ed25519と書かない限りrsa)、t=はフラグ(yはテスト、sは厳格)、h=はハッシュの制限、s=はサービスの制限です。空のp=は、意図的に鍵を失効させます。
タグ名は大文字と小文字を区別し、同じタグを繰り返すとレコードは無効になります。未知のタグは無視されます。
レコードをタグごとに
v=DKIM1; k=rsa; t=s; h=sha256; p=MIIBIjANBgkqhkiG9w…IDAQAB
| タグ | 設定内容 | 値 | 既定値 | 備考 |
|---|---|---|---|---|
| v= | バージョン | DKIM1 | DKIM1 | 推奨。ある場合は先頭 |
| k= | 鍵の種類 | rsa · ed25519 | rsa | 未知の種類:鍵は無視される |
| p= | 公開鍵(base64) | 鍵、または空 | 必須 | 空 = 失効 |
| t= | フラグ | y テスト · s 厳格 | なし | y:署名なしとして扱われる |
| h= | 許可するハッシュ | sha256(sha1は禁止) | すべて | sha1のみは失敗(RFC 8301) |
| s= | サービスの種類 | * | ほかのサービス専用:無視される | |
| n= | 人間向けのメモ | 任意のテキスト | – | ソフトウェアは読み取らない |
p=の長さと、必要なTXT文字列の数
255バイトごとのTXT文字列の境界(「v=DKIM1; k=rsa; p=」を含めて数えた場合)
2048ビットのRSAを使ってください。RFC 8301は、検証側に1024ビットの鍵を引き続き受け入れることを求めていますが、署名者には2048ビット以上を求め、1024ビット未満の鍵は拒否するよう検証側に求めています。 M3AAWGは1024ビットを「攻撃されかねない限界」と呼んでおり、512ビットの鍵が約72時間、約75ドルで解読されたと報告しています。
Ed25519鍵は小さく(p=は44文字)、下位互換のため、RFC 8463は署名者がそれと並べてRSA署名も付けることを認めています:セレクター2つ、署名2つです(RFC 8463)。
ローテーションは、新しい鍵を新しいセレクターに公開し、署名を切り替え、転送中のメールのために古い鍵を7〜30日残してから、そのp=を空にします。M3AAWGは半年ごとを勧めています。FastmailやMicrosoft 365のようなプロバイダーは、待機用のセレクターを使って自動で行います。
実際の鍵がRFC 8301の基準のどこにあるか
切れ目のないローテーション(M3AAWG)
DKIMが失敗するのは、署名されたバイト列が変更されたとき、鍵が見つからないとき、鍵が署名と一致しないときです。 メッセージを変更しない転送ではDKIMは保たれます(SPFとは異なります)。メーリングリストはフッターを追加したり件名にタグを付けたりするため、たいていDKIMを壊します。
このページの検証は、本文ハッシュとヘッダー署名を別々に確認するため、途中で付いたフッターと偽造を区別できます。
メーリングリストが153バイトのフッターを追加しました。ヘッダーはproject.exampleの鍵でまだ検証できるため、偽造ではありません。
対処 本文を変更しないリスト、またはARC(RFC 8617)を使い、あとの受信サーバーに元の結果が見えるようにします。
body-hash-mismatch署名後に署名されたヘッダーが変更された(リストがSubjectに自分の名前を追加する)か、セレクターに別の鍵が入っています。
対処 署名されたヘッダーを書き換えないこと。鍵を置き換えるのではなく、新しいセレクターに新しい鍵を公開します。
signature-mismatchs=2023old._domainkey.shop.exampleがNXDOMAINです:そのセレクターで署名されたメールが転送中なのに、セレクターが削除されました。
対処 切り替え後も古い鍵を7〜30日公開し続け、削除ではなくp=を空にします。
key-not-found転送: メッセージを変更せずに渡す転送サービスはDKIMを有効なまま保つため、SPFが失敗しても、DMARCは通常DKIMによって転送を乗り切ります。
SPFはどのサーバーがドメインの代わりに送信できるかを示し、DKIMはドメインが署名したことと変更されていないことを証明し、DMARCはその両方をFrom:アドレスに結び付け、失敗したときの扱いを指示します。
それぞれ別の問いに答えるため、3つとも必要です:GmailとYahooは一括送信者にSPFとDKIM、さらにDMARCレコードを求めており、RFC 9989はp=rejectのドメインに、SPFに頼らずDKIM署名を行うよう求めています。
3つのレコード、3つの問い
| 3つのレコード、3つの問い | SPF | DKIM | DMARC |
|---|---|---|---|
| 何を証明するか | このサーバーがMAIL FROMドメインの代わりに送信してよい | d=のドメインが署名し、署名された部分は変更されていない | From:が、SPFまたはDKIMに合格したドメインと一致する |
| どこにあるか | github.comのTXT | s1._domainkey.github.comのTXT | _dmarc.github.comのTXT |
| 現在のgithub.com | v=spf1 … ~all | 鍵12個、プロバイダー6社 | p=quarantine; sp=reject |
| 転送に耐えるか | いいえ:転送サービスのIPは登録されていない | 耐える。メッセージが変更されずに届く場合 | 耐える。アラインしたDKIMの合格によって |
| 壊れるとき | 新しい送信サービスがレコードにない | 本文または署名されたヘッダーが変更される | From:ドメインについて、どちらも合格しない |
元のメッセージを開いてDKIM-Signatureヘッダーを探します:d=は署名者、s=はどの鍵か、h=は署名されたヘッダーの一覧、bh=とb=は受信サーバーが確認する2つのハッシュです。
受信サーバーの判定は、到着時に追加される別のヘッダーにあります:Authentication-Results: … dkim=pass header.d=example.com header.s=dnsrobot-sample。英語表示のGmailの「Show original」ページは、これを「DKIM: 'PASS' with domain example.com」と要約します。
1通のメッセージに、署名者ごとに1つずつ、複数の署名が付くことがあります(あなたのドメインとメールサービス、またはメーリングリスト)。DMARCには、d=がアラインした有効な署名が1つあれば十分です。
サンプルメールの署名をタグごとに
v=11; a=rsa-sha2562; c=relaxed/relaxed3; d=example.com4; s=dnsrobot-sample5; t=17928331206; h=from:from:to:subject:date:message-id:mim…7; bh=fohb/a+auh1W9c…8; b=fF0aMr3Uo+mbgG…9
Authentication-Results: mx.example.net; dkim=pass header.d=example.com header.s=dnsrobot-sample
足りないものはありますか?機能や新しいツールを提案する