DKIM2

DKIM2 は、メッセージを取り扱うすべてのドメインに責任を負わせます。各署名をメッセージが実際にたどった経路に結び付けることで、受信者は、そのメッセージが誰宛てだったのか、どこから来たのか、そして途中で何が変更されたのかを検証できます。

作業中 · IETF Internet-Draft

このページは、dkim2.com(英語)のページを日本語に翻訳した非公式の日本語版です。内容に食い違いがある場合は、英語の原文が優先されます。デモサーバ、バリデータ、検証ツールは dkim2.com 上で提供されています。

ステータス: 作業中

DKIM2 は、IETF のDKIM ワーキンググループで策定が進められています。現在も活発に更新されている Internet-Draft であり、正式な標準ではありません。詳細は今後変更される可能性があります。

現在の DKIM では分からないこと

DKIM 署名が証明するのは、あるドメインがメッセージの何らかの版に署名した、という事実だけです。DMARC や ARC を組み合わせても、次の 3 点は確かめられません。

DKIM2 はどう解決するか

DKIM2 は、配送経路上のすべてのホップに責任を負わせます。各ホップは次のことを行います。

この仕組みは、2 つのメカニズムで成り立っています。1 つはMessage-Instance(MI)ヘッダで、各ホップにおけるメッセージのハッシュによるスナップショットです。もう 1 つは連鎖する DKIM2-Signature ヘッダで、各ホップが現在のスナップショットとそれ以前のすべての署名の両方に署名することで、作成者から受信者までを結ぶ、改ざんを検知できるチェーンを形成します。

この設計の根拠は、DKIM2 motivation draft にまとめられています。

実装とデモ

dkim2.com では、稼働中の DKIM2 デモサーバが運用されています。Python、Perl、Go、C による 4 つの独立した実装が、プロジェクトのリポジトリ内で相互運用されています。dkim2.com 上の 2 つのメーリングリスト管理ソフトウェアは、メールを転送する際に DKIM2 で署名します。

これらのいずれかのリストに登録すると、DKIM2 署名付きのリストメールを受信でき、リストによる各種の変更がどのように記録されるかを確認できます。

その他の DKIM2 実装

DKIM2 は、複数の場所で独立して開発が進められています。以下は、dkim2.com のデモサーバ以外で確認されている取り組みです。

実装作者言語概要
croessner/dkim2 Christian Rößner Go dkim2d デーモン、milter、Exim の local_scan。署名と検証の両方を行います。Apache-2.0
go.turscar.ie/dkim2 Steve Atkins Go ライブラリと、dkim2sign、dkim2verify、dkim2explain の各コマンドラインツール。BSD-2-Clause
turscar/dkim2tests Steve Atkins — 適合性テストベクタ — このプロジェクトのすべての検証実装が実行対象とするテスト一式。BSD-2-Clause
mail-auth Stalwart Labs Rust ライブラリ。Ed25519 と RSA による署名とチェーン検証に対応し、1 つの署名の中に複数のセレクタを持てます。Apache-2.0 または MIT
SocketLabs DKIM2 verify SocketLabs ホスト型 ブラウザおよび JSON API で利用できる検証サービス。dkim2.net からもアクセスできます
dkim2.eu 運営者の記載なし ホスト型 独自の実装一覧を備えた、バリデータ兼解説サイト

2026 年 8 月時点の調査に基づきます。ここに掲載すべき DKIM2 実装に取り組んでいる方、またはご自身の実装についての誤りに気付いた方は、ぜひお知らせください。

試してみる: リフレクタアドレス

dkim2.com のアドレスを使うと、DKIM2 の動作をエンドツーエンドで確認できます。種類は 3 つあります。送ったメッセージを下記の所定の変換を加えて送り返すリフレクト用が 6 つ、あなた宛てに新しいメッセージを発信するものが 3 つ(新しいメッセージの発信)、バウンスと配送通知を実演するものが 2 つです(バウンスと配送通知)。

たとえばリファレンス実装から、DKIM2 署名付きのメッセージを reflector-*@dkim2.com のアドレスへ送ってください。下表のモードに従って変換された返信が届きます。返信に署名が付くかどうかは、そのメッセージがどのように認証されたかによって決まります(返信に署名が付く場合を参照)。署名の有無にかかわらず、返信には、何が起きたかを説明する Authentication-Results ヘッダと X-DKIM2-Reflector ヘッダが含まれます。返信をバリデータに貼り付けると、結果を確認できます。

アドレス動作期待される結果
reflector-raw@dkim2.com 変更のないメッセージに再署名します チェーンが問題なく検証されます
reflector-subject@dkim2.com 件名の先頭に [DKIM2]  を付加します 検証に成功します。変更は元に戻せるため、元の件名が復元されます
reflector-body@dkim2.com 本文の末尾にフッター行を追加します 検証に成功します。変更は元に戻せるため、元の本文が復元されます
reflector-both@dkim2.com 件名プレフィックスと本文フッターの両方 検証に成功します。両方の変更が元に戻せます
reflector-redacted@dkim2.com 本文を変更し、元に戻せない変更として記録します (r={"b":null}) draft -09 では PERMERROR(「null レシピがある」)になります。元の本文を復元して確認することができないため、検証を完了できません。受け入れるかどうかはローカルポリシー次第です
reflector-damage@dkim2.com 署名した後に本文を改変します 本文ハッシュの検証が失敗します — 改ざん検知が働いている例です

注: body / both のフッターは、生のメッセージ本文の末尾に追加されます。multipart/* のメッセージでは、MIME のエピローグ(終端バウンダリの後ろ)に置かれるため、ほとんどのメールクライアントでは表示されません。ただし、生のバイト列には存在し、本文ハッシュの対象となり、Message-Instance のレシピにも記録されます(そのため、変更は引き続き検証でき、元に戻せます)。単純な text/plain のメッセージでは、フッターが表示されます。

返信に署名が付く場合

リフレクタが自身の dkim2.com のチェーンリンクを追加するのは、そのメッセージを保証できる場合に限られます。

メッセージを変更するすべてのモード(subject、body、both、redacted)では、返信に署名が付くかどうかにかかわらず、変更を記録する Message-Instance が追加されます。

返信されたメッセージで確認するヘッダ

ヘッダ分かること
X-DKIM2-Reflector リフレクタによる要約です。mode、確認した判定結果(auth = DKIM2、dkim1)、署名の根拠(basis = dkim2/dkim1/none)、そして signed が含まれます。
Authentication-Results リフレクタが根拠とした dkim2= の結果と、(ブリッジが適用された場合は)dkim=pass header.d= の結果です。
DKIM2-Signature 返信に署名が付いた場合にのみ存在します — チェーンにおけるリフレクタのリンクです。
Message-Instance リフレクタによる変更を記録した m= のスナップショットです(変更を行うモードで存在します)。
DKIM-Signature(従来の DKIM1) すべての返信には、通常の DKIM1 署名も付きます(d=dkim2.com。brand アドレスでは、d=<your-domain> の署名がさらに 1 つ付きます)。これにより、デモメールが実際の運用メールのように扱われます。

新しいメッセージの発信

3 つのアドレスは、あなたのメッセージを返すのではなく、まったく新しい DKIM2 メッセージを発信して、あなたに送ります。dkim2.com と整合した送信元から送信されるため、返信は DMARC に合格し、受信トレイに届きます。

reflector-fresh@dkim2.com

最もシンプルな有効な DKIM2 メッセージを生成します。Message-Instance が 1 つ(m=1)、dkim2.com の DKIM2-Signature が 1 つで、転送チェーンはありません。これに加えて、対応する dkim2.com の DKIM1 署名も付きます。送信元は <fresh@dkim2.com>、宛先はあなたです。バリデータに貼り付けると、クリーンな署名 1 つとインスタンス 1 つを確認できます。

reflector-brand@dkim2.com — ブランド委任

ブランドに代わって、自身の識別情報を表に出さずに送信するメール配信プラットフォーム(ESP)をモデル化したものです。DNS レコードを 1 つ設定するだけで署名鍵を dkim2.com に委任でき、その結果、あなたのドメインとして署名されたまったく新しいメッセージが返されます。

委任された d=<your-domain> の DKIM1 が From: ドメインと整合するため、メッセージは DMARC に合格して受信トレイに届きます。これは、Mailchimp や SendGrid などのプラットフォームが、現在ブランドに代わって送信している方法と同じです。(<your-domain> には、ご自身のドメイン名を入れてください。)

セットアップ — CNAME を 1 つ公開します(あなたのドメインの DNS に):

dkim2test._domainkey.<your-domain>.  CNAME  dkim2test._domainkey.dkim2.com.

この 1 つの委任で、DKIM2 のチェーン署名と DKIM1 署名の両方がまかなわれます。つまり、dkim2.com が保持する 1 つの鍵を、あなたのドメインが使用を許可する形です。その後、そのドメインのアドレスから reflector-brand@dkim2.com にメールを送り、返信をバリデータに貼り付けて、2 つの DKIM2 署名がどちらも検証される様子を確認してください。

CNAME が設定され(かつ伝播し)終わるまでは、このアドレスは、委任の設定方法を説明する、reflector-fresh 形式の簡素なメッセージを返信します。

reflector-brand-nd@dkim2.com — nd= によるブランド委任

reflector-brand と同じブランド委任ですが、i=1 のブランドのホップは、mf=/rt= ではなく、nd=(「次のドメイン」、架空のホップの形式、draft §12.3)によるエンコードを使います。最初のリンクは、エンベロープの経路ではなく、次に署名するドメインを指名します。チェーンは引き続き検証されます — i=1 の nd= が、i=2 の d=(dkim2.com)と一致します。セットアップは reflector-brand と同じ、CNAME 1 つです。返信をバリデータに貼り付けて、nd= のリンクが検証されることを確認してください。

バウンスと配送通知

2 つのアドレスは、DKIM2 が配送状況通知(DSN)、つまり MTA がメッセージを配送できないときに送るバウンスをどのように扱うかを示します。仕様では、DKIM2 の DSN はそれ自体が通常の DKIM2 メッセージです。エンベロープは MAIL FROM <> で、最上位のメッセージに固有の Message-Instance と DKIM2-Signature を持ち、失敗したメッセージが記録したリターンパス宛てに送られます。

reflector-dsn@dkim2.com — DKIM2 署名付きの DSN

あなたのメッセージを受け付け、そのメッセージに対する、新しく署名された DSN を返します。元のメッセージを message/rfc822 パートとして埋め込んだ multipart/report で、Message-Instance 1 つと dkim2.com の DKIM2-Signature 1 つを自身で持ちます。クリーンな 1 ホップの DKIM2 メッセージです(あなたのチェーンの継続ではありません)。DKIM2 署名付きで届いたかどうかにかかわらず、すべてのメッセージをバウンスします。返信をバリデータに貼り付けると、DSN が新しい 1 ホップのメッセージとして検証される様子を確認できます。

reflector-delayedbounce@dkim2.com — MTA が発生させるバウンス

上記のすべてのアドレスとは異なり、これはリフレクタによる変換ではありません。このアドレスは SMTP プロンプトで受理され(250 が返るため、送信セッションは正常に完了します)、その後の配送で失敗します。そのため、このバウンスは本物の遅延バウンスであり、セッションが終わった後に、実際の遅延失敗とまったく同じように、Postfix 自身のバウンス生成機能(bounce(8))によって非同期に生成されます。送信側の DKIM2 milter は、そのバウンスを送り出す際に、新しい DKIM2 メッセージ(固有の Message-Instance と DKIM2-Signature、MAIL FROM <>)として署名します。署名されたバウンスはそれ自体が有効な DKIM2 メッセージであり、検証に成功します。これは、リフレクタのコードではなく MTA が生成する、メールサーバ自身のバウンスにも DKIM2 署名を付けられることを示しています。 (運用上の要件が 1 つあります。milter が署名した後で、MTA がメッセージを再エンコードしてはなりません。署名を壊してしまう 8bit→7bit の書き換えを防ぐため、disable_mime_output_conversion を設定しています。仕様の「Preventing Transport Conversions」を参照してください。)

さらに詳しく