Carpe Diem

備忘録

メールにおけるDKIMの仕組み

概要

前回SPFについて説明しました。

christina04.hatenablog.com

今回は署名によってヘッダ・メール本文の改ざんを検知するDKIMについて説明します。

フロー図

DKIMの検証フロー

DKIMの検証フローは以下です。

f:id:quoll00:20200920134658p:plain

説明すると

  1. あらかじめペア鍵を用意しておく
  2. 公開鍵をDKIMレコード(実際はTXTレコード)に登録しておく
  3. メールを秘密鍵で署名し、DKIM-Signatureヘッダとして追加
  4. 受信サーバはDKIM-SignatureヘッダのdタグsタグからDKIMレコードを参照
  5. DKIMレコードの公開鍵で署名を検証

となります。

ドメインとは別サービスでメールを送る場合

自前でメールサーバを構築するのは大変なので、SaaSを利用するケースも多いでしょう。
その中で大きく2通りのやり方があります。

SaaSから公開鍵を受け取って自ドメインDKIMレコードに登録

MailgunというSaaSはこちらのパターンです。

f:id:quoll00:20200919035250p:plain

レコード参照

こんな感じで自ドメインで公開鍵を参照できるようにしておきます。

$ dig bris._domainkey.hogehoge.dev txt
;; ANSWER SECTION:
bris._domainkey.hogehoge.dev. 300 IN    TXT     "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEC2v7EWS1Hpsryyq5XaWTVQ/32dcYyeQk4SALmp5gVS9a80+XzQyN2MorlLBDSWvO7TjCuwhipnjkldEg9pRKeza7jVU2pzVIsjvW/KcfZMDmoGLitOzymIsHtGE+/4vgMINTJabe5r1K61W3ccFXscQ2Av9O26ieRvSQiMmvCQIDAQAB"

SaaSDKIMレコードへのCNAMEレコードを登録

AWS SESの場合はこのパターンです。

f:id:quoll00:20200919035311p:plain

レコード参照

ドメインにはCNAMEレコードが登録されており、

$ dig bris._domainkey.hogehoge.dev cname
;; ANSWER SECTION:
bris._domainkey.hogehoge.dev. 3600 IN CNAME bris.dkim.amazonses.com.

SESの方でDKIMレコードに公開鍵があります。

$ dig bris.dkim.amazonses.com txt
;; ANSWER SECTION:
bris.dkim.amazonses.com. 3600 IN TXT "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIjll2k5v2pNK4BAxoH1QSDYnCngapftVFRauG3jzh5dFMpYyJJypNQxNoA06EIvN6f22E461kmzWZk19Ym8jhDE7Zd+4sE1NbBDzHPl3K23avk+En5Jc6Xci7B1tU2ptxyZOk4jCVEof9iMa3n9kNA+V9JNbo+kCEaEcxLAozmQIDAQAB"

ちなみにこれは自ドメインへのDKIMレコード参照で一発で取れます。

$ dig bris._domainkey.hogehoge.dev txt
;; ANSWER SECTION:
bris._domainkey.hogehoge.dev. 3600 IN CNAME bris.dkim.amazonses.com.
bris.dkim.amazonses.com. 3600 IN TXT "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIjll2k5v2pNK4BAxoH1QSDYnCngapftVFRauG3jzh5dFMpYyJJypNQxNoA06EIvN6f22E461kmzWZk19Ym8jhDE7Zd+4sE1NbBDzHPl3K23avk+En5Jc6Xci7B1tU2ptxyZOk4jCVEof9iMa3n9kNA+V9JNbo+kCEaEcxLAozmQIDAQAB"

詳細

DKIM-Signatureヘッダ

先程まではフローで全体感を説明しました。
次はDKIM-Signatureヘッダについて少し詳細を説明します。
DKIM-Signatureヘッダには以下のタグが含まれています。

フィールド名 説明
a 署名アルゴリズム
v バージョン
c メール本文やヘッダの正規化方式
d 署名を行ったドメイン。送信ドメイン
DMARC準拠するにはFromヘッダと一致させる。
異なる場合は第三者署名と呼ばれる
q 公開鍵を取得する方法を指定。現時点ではdns/txtのみ指定可能。省略時はdns/txt
s 公開鍵を取得する際のDNSクエリに利用。
s=picならpic._domainkey.ドメインのTXTレコードに公開鍵を置いてある、となる
t 署名した日時
h 署名を作成するデータに含めるヘッダ
bh メール本文のハッシュ値
b hのヘッダとメール本文に対しての署名

具体的には以下のような値になります。

DKIM-Signature: a=rsa-sha256; v=1;
  c=relaxed/relaxed; d=mail.hogehoge.dev;
  q=dns/txt; s=pic; t=1600418594;
  h=Mime-Version: Content-Type: Subject: From: To: Reply-To: Message-Id: Sender: Date: Content-Transfer-Encoding;
  bh=1GG/AllToIAaOWd7dXyW/8Kmpo1HuZzB9v/b+N8+aWQ=;
  b=CmdzyhfWoOsVp0q2mFqZaw5dYNc6SsN2BhGiqHisBxWhZhmYSB+tRryW+5TTMMfPukZIbM8f 

公開鍵はヘッダのタグが

  • d=mail.hogehoge.dev
  • s=pic

なのでpic._domainkey.mail.hogehoge.devのTXTレコードに登録していることになります。

$ dig pic._domainkey.mail.hogehoge.dev txt
;; ANSWER SECTION:
pic._domainkey.mail.hogehoge.dev. 300 IN    TXT     "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEC2v7EWS1Hpsryyq5XaWTVQ/32dcYyeQk4SALmp5gVS9a80+XzQyN2MorlLBDSWvO7TjCuwhipnjkldEg9pRKeza7jVU2pzVIsjvW/KcfZMDmoGLitOzymIsHtGE+/4vgMINTJabe5r1K61W3ccFXscQ2Av9O26ieRvSQiMmvCQIDAQAB"

DKIMの欠点

DKIMはメールが改ざんされていないかをチェックする仕組みであるため、

という問題があります。

hタグ以外のヘッダを変更、追加して再送しても署名的には通る

DKIM署名の仕様はヘッダとメール本文を署名したものですが、このヘッダはhタグで指定している一部のヘッダのみになります。
なのでhタグに含まれていないヘッダに関して改ざん・追加されたとしてもDKIMの署名検証は通ります。

dタグのドメインが送信サーバのドメインとは限らない

署名検証が通ったメールは一部ヘッダや本文が改ざんされていないことを保証しますが、メッセージリプレイする、つまりそのメール自体を別のサーバから送信することは可能です。メッセージが改ざんされていないのでDKIM検証も当然通ります。

DKIMはあくまで署名による改ざん防止をするだけで、送信したサーバがDKIM-Signatureヘッダのドメイン(dタグ)所有者のサーバであるかのチェックはしないからです。

こういった理由からSPFとあわせて検証することで、送信サーバも正しいことをチェックすべきです。

まとめ

なりすましメール対策としてのSPFDKIMをそれぞれ説明しました。

どちらも対策している範囲が異なるので、両方実施するかつDMARCを利用することでより信頼性のあるメールを送ることができます。

参考