【DKIMの仕組み】
メールに付加された電子署名を検証し、送信中に内容が改ざんされていないか、正規のサーバーから送られたものかを検証します。
基本的な流れ
DKIMは、公開鍵暗号方式を使用しています。
デジタル署名の生成:
送信者のメールサーバーは、送信する各メールに独自のデジタル署名を作成します。この署名は、送信者だけが知っている秘密鍵を使って生成されます。署名は、メールのヘッダーと本文のハッシュ(要約データ)です。
DNSレコード:
対応する公開鍵は、送信者のDNS(Domain Name System)レコードに公開されます。この公開鍵は誰でもアクセスできます。
検証:
受信者のメールサーバーは、メールを受信すると、送信者のドメイン名を使ってDNSレコードから公開鍵を探し、その公開鍵でデジタル署名を復号します。
→ 詳細:
受信サーバーは:
- メールヘッダーのDKIM-Signatureフィールドから下記の情報を取得
-
d=タグから、DKIM署名ドメイン -
s=タグから、DKIMセレクタ
-
- 上記の情報を用いて、DKIM署名ドメインのDNSレコードから公開鍵(DKIMレコード)を取得
- 取得した公開鍵を使って、メールに付与されたデジタル署名を検証
- 署名が有効であれば、メールが改ざんされていないことと送信者の正当性を確認
認証:
受信側のサーバーは、メールのヘッダーと本文のハッシュを再計算し、復号した署名からのハッシュと比較します。
- ハッシュが一致すれば、メールは認証されたとみなされ、正当な送信者から送られ、改ざんされていないと判断されます。
- ハッシュが一致しない場合、メールは未検証とされ、スパムとしてフラグが付けられたり、拒否されたりする可能性があります。
【なぜこの認証で正規のメールと判断できるか?】
正規のドメイン所有者またはその代理人だけが、DNSレコードを編集する権限を持っています。DKIMの仕組みは、この信頼の連鎖に基づいています。
-
ドメインの所有権:DNSレコードを編集できるということは、そのドメインの所有者であることを証明します。
-
公開鍵の登録:この権限を持つ正規の人物だけが、ドメインのDNSにDKIMの公開鍵を登録できます。
-
秘密鍵の作成と使用:その公開鍵と対になる秘密鍵は、そのドメインの正規のメールサーバー(または、正規のドメイン所有者が許可した外部のメールサービス)によって作成・管理されます。
したがって、DNSに登録された公開鍵は、その公開鍵と対になる秘密鍵が正規の人物または組織によって管理されていることを間接的に証明しています。このプロセスにより、受信側のメールサーバーは、メールが信頼できる送信元から送られたことを確認できるのです。
【DKIMレコード確認方法】
概要
DKIMレコードがDNSに存在するかどうかを確認するには、DNSルックアップツールを使用します。このツールを使って、特定のセレクターとドメイン名に対応するTXTレコードを照会することで確認できます。
確認方法
DNSルックアップ: コマンドラインツール(dig や nslookup)またはオンラインのDNSルックアップサービスを使用して、上記形式のホスト名をクエリします。
コマンドラインツールによる確認例
Linux/macOSの場合(digコマンド):
dig TXT <selector>._domainkey.<example.com>
Windowsの場合(nslookupコマンド):
nslookup -type=TXT <selector>._domainkey.<example.com>
-
<selector>はDKIM署名に使用される識別子- セレクタの特定: メールヘッダーからDKIM-Signatureフィールドを探し、s=で始まるセレクタの値を確認します。例えば、
s=selector1の場合、セレクタは selector1 です。
- セレクタの特定: メールヘッダーからDKIM-Signatureフィールドを探し、s=で始まるセレクタの値を確認します。例えば、
-
<domain_name>は送信メールのドメインです。 -
._domainkey.は固定の値。
上記のコマンドを実行すると、以下のような結果が表示されます。
-
レコードが存在する場合: DKIMの公開鍵を含むTXTレコードが表示されます。その値は
v=DKIM1; k=rsa; p=<公開鍵の文字列>のような形式になっています。 -
レコードが存在しない場合: レコードが見つからないことを示すメッセージが表示されます
Authentication-Resultsのheader.iとDKIM-Signatureのd=の関係について詳しく説明します。
【DKIM署名の2つの識別子】
DKIM署名には2つのドメイン識別子があります:
📝 DKIM-Signatureヘッダの構造
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=selector1;
h=from:to:subject:date:message-id;
bh=base64hash...;
b=signature...;
i=user@example.com
1️⃣ d= (Signing Domain Tag) - 必須
- 署名ドメイン
- このドメインの秘密鍵で署名されたことを示す
- DNS上の公開鍵の場所:
selector1._domainkey.example.com - 必須パラメータ
2️⃣ i= (Agent or User Identifier) - 任意
- 署名者識別子
- 実際に署名した主体(ユーザーやエージェント)を示す
- オプションパラメータ(省略可能)
- 省略時のデフォルト値:
@d=のドメイン
d=とi=の関係とルール
📏 制約条件
重要ルール: i=のドメイン部分は、d=と同じか、そのサブドメインでなければならない
❌ 無効な組み合わせ
d=example.com
i=user@other-domain.com
→ 異なるドメイン ❌ (署名検証失敗)
d=mail.example.com
i=user@example.com
→ i=がd=の親ドメイン ❌ (署名検証失敗)
d=mail.example.com
i=user@other.example.com
→ 兄弟サブドメイン ❌ (署名検証失敗)
i=が省略された場合
デフォルト動作
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector1; ...
(i=パラメータなし)
→ i=@example.com として扱われる
i=の実用的な用途
🔍 1. 詳細なログ・追跡
複数のシステムやユーザーが同じd=ドメインで署名する場合の識別:
d=company.com
i=sales-team@company.com
→ 営業チームのメールサーバーから送信
d=company.com
i=support-team@company.com
→ サポートチームのメールサーバーから送信
DNSでの公開鍵配置
i=の値に関わらず、公開鍵はd=とs=で決まる場所に配置: