本文へスキップ
サイト総合診断

DKIM とは — 電子署名でメールの改ざんを検知する

DKIM は、送信サーバーがメールに電子署名を付け、受信側が DNS 上の公開鍵でそれを検証する仕組みです。署名が通れば、そのメールが確かにそのドメインの鍵で送られ、途中で本文が改ざんされていないことが分かります。差出人を名乗るだけで送れてしまうメールに、後から「本物である証拠」を足すのが DKIM です。

執筆: 公開:

DKIM とは何ですか?

DKIM は、送信サーバーがメールに電子署名を付け、受信側が DNS 上の公開鍵で検証する仕組みです。署名が検証できれば、そのメールが署名ドメインの鍵で送られ、途中で改ざんされていないことが分かります。SPF が送信元の IP を照合するのに対し、DKIM は署名そのもので正当性を示すため、転送されても検証が保たれます。

メールの差出人は、誰でも自由に名乗れます。SPF・DMARC がこの欠陥を DNS で補う仕組みであるのに対し、 DKIM はメールそのものに電子署名を付けて「本物である証拠」を運ばせるアプローチです。証明できることは、次の 2 つに整理できます。

  • 改ざんされていないこと — 署名対象の本文とヘッダーが、送信されてから 1 文字も書き換わっていない
  • そのドメインの鍵で署名されたことd= で示されたドメインの秘密鍵を持つ者が署名した

言い換えると、DKIM が保証するのは「誰が署名したか」と「中身が無傷か」です。この署名を From: と結びつけて処遇を決めるのは DMARC の仕事で、 DKIM 単体は「失敗したらどうするか」までは面倒を見ません。ここは後半で改めて触れます。

DKIM はどういう仕組みで動きますか?

送信サーバーが秘密鍵でメールのヘッダーと本文に署名し、その値を DKIM-Signature ヘッダーに載せて送ります。受信側は署名ドメインの DNS から公開鍵を取り出して署名を検証します。秘密鍵は送信側だけが持ち、公開鍵は誰でも引ける DNS に置くという公開鍵暗号の構造で、鍵を配布せずに真正性を確認できます。

DKIM は公開鍵暗号の上に成り立っています。鍵はペアで、役割がはっきり分かれます。

  • 秘密鍵 — 送信サーバーだけが持つ。これでメールに署名する。外に出さない
  • 公開鍵 — 誰でも引ける DNS に置く。受信側はこれで署名を検証する

送信時、サーバーは本文と指定したヘッダーからハッシュを計算し、秘密鍵で署名して DKIM-Signature ヘッダーに詰めます。 受信側は署名の d=s= から公開鍵の在り処を割り出し、DNS から鍵を取得して署名を検算します。秘密鍵を渡さずに真正性を確認できるのが、この構造の要点です。攻撃者は公開鍵を読めても、秘密鍵が無ければ有効な署名を作れません。

公開鍵はどこに置かれ、セレクタとは何ですか?

公開鍵は「セレクタ._domainkey.ドメイン」という名前の TXT レコードに置かれます。セレクタは送信側が自由に決める短い名前で、これにより 1 つのドメインで複数の鍵を持てます。送信サービスごとに別のセレクタを割り当てられ、鍵の入れ替えも、新しいセレクタを足すだけで配送を止めずに行えます。

公開鍵の場所は <セレクタ>._domainkey.<ドメイン> という名前の TXT レコードに固定されています。 可変なのはセレクタの部分だけで、ここは送信側が任意に決めます(例: brevo1googles7f3k)。 このセレクタという「取っ手」があるおかげで、次のことが自然に実現します。

  • 複数の鍵を同時に持てる — 送信サービスごとに別セレクタを割り当てれば、鍵が互いに衝突しない
  • 無停止で鍵を交換できる — 新しいセレクタで新鍵を公開し、送信を切り替えてから旧セレクタを畳む
DNS 上の公開鍵(TXT レコード)
; 公開鍵は <セレクタ>._domainkey.<ドメイン> の TXT レコードに置く
brevo1._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEF...(2048bit の公開鍵)"

; ★ セレクタが違えば、同じドメインで複数の鍵を同時に持てる。
;   送信サービスごとに別セレクタ = サービスを増やしても鍵が衝突しない
google._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEF..."

; ★ 鍵の失効は p= を空にする。「この鍵での署名はもう無効」の明示
old._domainkey.example.com.     IN  TXT  "v=DKIM1; p="

DKIM-Signature ヘッダーには何が入っていますか?

署名ドメインを表す d=、鍵を指すセレクタ s=、本文のハッシュ bh=、署名値 b=、署名対象のヘッダー一覧 h= などのタグが並びます。受信側はまず bh= で本文が改ざんされていないかを確かめ、次に b= を公開鍵で検証します。この 2 段階で、本文と署名対象ヘッダーの真正性が保証されます。

実際の DKIM-Signature ヘッダー
; 送信されるメールに実際に付く DKIM-Signature ヘッダーの例
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  d=example.com; s=brevo1;
  h=from:to:subject:date:message-id;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
  b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lsz...

; a=  署名アルゴリズム(rsa-sha256 が一般的)
; d=  署名ドメイン。DMARC はこれが From: と揃うかを見る
; s=  セレクタ。d= と組み合わせて DNS の公開鍵を特定する
; bh= 本文のハッシュ。本文が改ざんされていないかの確認に使う
; b=  署名値。h= で指定したヘッダーへの署名本体
; h=  署名対象のヘッダー一覧。ここに無いヘッダーは保護されない

主なタグと、検証でそれぞれが果たす役割を表にまとめます。

DKIM-Signature の主なタグ
タグ意味検証での役割
d=署名したドメインDMARC が From: と揃うかを見る
s=セレクタ(公開鍵の場所)d= と組み合わせて DNS の鍵を特定する
bh=本文のハッシュ本文が改ざんされていないかを確認する
b=署名値公開鍵で検証する署名の本体
h=署名対象のヘッダー一覧どのヘッダーを保護したかを示す

DKIM が転送に強いのはなぜですか?

DKIM は署名がメール自体に付くため、本文が書き換わらない限り、転送されても検証できるからです。SPF は接続元 IP を照合する仕組みなので、転送されると接続元が転送サーバーに変わり、正当なメールでも失敗します。この違いから、メーリングリストや自動転送を挟む経路では DKIM のほうが壊れにくく、両方を併用する価値があります。

SPF と DKIM は「何を根拠に正当性を測るか」が根本的に違います。この差が、転送時の強さの差になって現れます。

転送に対する SPF と DKIM の違い
SPFDKIM
照合するもの接続元の IP アドレスメールに付いた電子署名
転送されると接続元が転送サーバーに変わり失敗しやすい署名は残るので検証できる
壊れる条件経路が正規の送信元 IP を通らないとき本文や署名対象ヘッダーが書き換わったとき

メーリングリストや .forward による自動転送では、受信側から見える接続元 IP が転送サーバーのものに変わります。 SPF はこの IP を照合するため、正当なメールでも fail してしまいます。一方 DKIM の署名はメール自体に貼り付いて一緒に運ばれるので、 本文が改ざんされない限り、転送後も検証が通ります。だから SPF と DKIM は二者択一ではなく、両方を入れるのが正解です。

DKIM の鍵はどう管理・交換すればよいですか?

鍵は 2048bit を推奨し、定期的に新しい鍵へ入れ替えるのが望ましい運用です。セレクタを使えば、新しい鍵を別セレクタで公開してから送信側を切り替え、古いセレクタを残したまま移行できるので、配送を止めずに交換できます。秘密鍵が漏れた場合も、該当セレクタの公開鍵を失効させれば、その鍵での署名を無効にできます。

鍵は長期間使い続けるほど、漏洩や解読のリスクが積み上がります。そこで鍵長は 2048bit を推奨し、 定期的に新しい鍵へ入れ替えるのが望ましい運用です。セレクタがあるおかげで、この交換は配送を止めずに行えます。

  • 新しいセレクタで新しい公開鍵を DNS に公開する(この時点では旧鍵も生きている)
  • 送信サーバー側の署名を新しい鍵に切り替える
  • 旧セレクタでまだ署名されたメールが届く可能性がある間は、旧鍵を残しておく
  • 十分に時間が経ってから、旧セレクタの公開鍵を p= を空にして失効させる

秘密鍵が漏れたときも同じ手順が効きます。該当セレクタの公開鍵を失効させれば、その鍵で作られた署名はすべて無効になります。 鍵を 1 本で運用していると、この切り替えがそのまま配送停止につながりかねません。セレクタを分けておく価値はここにあります。

DKIM と DMARC はどう関係しますか?

DKIM 単体は「検証に失敗したメールをどう扱うか」を決めません。失敗時の処理を指示するのは DMARC の役割です。DMARC は SPF と DKIM の結果を束ね、どちらかが From: ドメインと揃って通れば認証成功とみなし、両方失敗したときに隔離や拒否を発動します。DKIM は DMARC を支える 2 本の柱の 1 つです。

DKIM は「このメールは d= のドメインの鍵で署名され、中身は無傷だ」とだけ言います。その署名が、受信者に見える From: のドメインと一致しているか、 そして検証に失敗したメールを配送するのか隔離するのか拒否するのか——これらを決めるのは DKIM ではなく DMARC です。

DMARC は SPF と DKIM の結果を束ね、どちらか一方でも From: と揃って通れば認証成功とみなします。 両方が失敗して初めて、ドメイン所有者が指定した処遇(quarantine / reject)が発動します。 DKIM は転送に強く、SPF は設定が単純——性質の違う 2 つを DMARC が束ねることで、実運用に耐える認証になります。

DKIM が設定できているか確認するには?

セレクタ名が分かっていれば、dig でその TXT レコードを引いて公開鍵の有無を確認できます。セレクタは送信サービスの管理画面に書かれています。届いたメール側では、ヘッダーの DKIM-Signature と Authentication-Results を見れば、どのドメインの鍵で署名され、検証が pass したかを確認できます。

DKIM を確認する
# セレクタ名が分かっていれば、その公開鍵を直接引ける
dig +short TXT brevo1._domainkey.example.com

# 受信済みメールの署名を確認するなら、ヘッダーを見る
#   DKIM-Signature:          どのドメイン(d=)・どのセレクタ(s=)で署名されたか
#   Authentication-Results:  dkim=pass header.d=example.com なら検証成功

# セレクタ名が分からないと外から鍵は引けない。
# セレクタは送信サービス(Google Workspace / Microsoft 365 / Brevo など)の
# 管理画面に書いてある。DNS からレコードを列挙する手段は存在しない

確認には 2 つの方向があります。送る側としては、セレクタ名さえ分かれば dig で公開鍵の TXT を直接引けます。 セレクタは送信サービスの管理画面に必ず書いてあるので、そこを見るのが最短です。受け取った側としては、メールの DKIM-SignatureAuthentication-Results ヘッダーを開けば、 どのドメインの鍵で署名され、検証が pass したかを読み取れます。

ただし、外部から「そのドメインに DKIM が無い」ことは証明できません。セレクタ名は送信側が自由に決められ、 DNS からレコードを列挙する手段が存在しないためです。本ツールもよく使われるセレクタを推測で照会するだけで、 見つからなくても「未設定」とは断定しません。この限界を含めた判定の考え方は SPF・DMARC でなりすましメールを防ぐ で詳しく説明しています。

参考にした一次情報

関連する解説

自分のサイトは、実際どうなっているか

この記事で説明した項目は、すべて無料の診断ツールで実測できます。URL を入れるだけ・登録不要です。

無料で診断する