DKIMについて調べたよ

# はじめに
なぜ調べたのかは前回の記事を参照していただきたく
SPFについてはなんとなくわかったので、併せて使用することが多いDKIMについても調べて備忘録として残す

# DKIMとは
- Domainkeys Identified Mailの略
- 電子署名方式の送信ドメイン認証である
    - メール送信側で電子メールに電子署名を付加して受信側で電子署名の照合を行う
    - メッセージのヘッダや本文を元に電子署名を作成するので、メールの転送であっても転送先で認証が可能
- 仕組みのイメージ図
![DKIM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266246/d03e73ed-6b97-d2fa-afc3-790b2f1a4801.png)
① DNSサーバに電子署名に使う公開鍵を登録しておく
② メールサーバにてメールのヘッダおよび本文から電子署名を作成、付与する
③ 電子署名付きメールをSMTPで送信する
④,⑤ 届いたメールからDKIM-Signatureで指定されたドメインのDNSへ公開鍵の問い合わせを行う
⑥ 取得した公開鍵より電子署名を照合してOKであれば認証成功

# DKIMのDNS設定
- メールを送信する側のドメインを管理するDNSサーバを使って署名に利用する公開鍵を公開する
- FQDNに対するTXTレコードとしてDNSに登録する
    - 形式は【＜セレクタ＞._domainkey.＜ドメイン名＞】で登録する
        - セレクタ
            - メールのヘッダにあるDKIM-Signatureヘッダ"sタグ"にしたラベルを使用
            - 異なるセレクタを用意することで同じドメインで複数の公開鍵を運用できる
        - ドメイン名
            - メールのヘッダにあるDKIM-Signatureヘッダ"dタグ"にしたラベルを使用
        - **設定の例**
            
            |ホスト名|TYPE|TTL|クラス|VALUE|
            |---|---|---|---|---|
            |sample._domainkey.example.com.|TXT|5分|IN|"v=DKIM1; k=rsa; t=y; p=zxcvbnm...\<以下略\>"|


            |タグ|タグの意味|説明|省略できるか|
            |---|---|---|---|
            |v|Keyレコードの<br>バージョン番号|指定する場合は「DKIM1」と設定する<br>省略時には「DKIM1」と設定される<br>指定する場合は、レコードの最初に記述しなければならない|設定推奨<br>省略可能|
            |g|鍵の適用条件パターン|電子署名の対象とするメールアドレスの@の前にマッチする条件を指定する<br>ワイルドカード文字を利用することができる<br>省略時は「*」が設定される|省略可能|
            |h|利用可能な<br>ハッシュ方式|電子署名の作成の際に利用できるハッシュ方式を限定できる<br>すべてのハッシュ方式を許容することができる<br>DKIMではSHA1とSHA256のみサポートされている<br>署名作成者と照合者がSHA256方式をサポートする必要あり<br>照合者はSHA1もサポートする必要がある|省略可能|
            |k|鍵の方式|電子署名の作成で利用できる鍵の方式を指定する<br>DKIMではRSA形式のみサポートしている<br>省略時は「RSA」が指定される|省略可能|
            |n|説明文を記載|可読な説明文を記載できるタグ<br>省略時は表示されない|省略可能|
            |p|公開鍵データ|公開鍵データを設定しておくタグ<br>鍵データはBASE64でエンコードする必要がある<br>値が設定されていない場合には、該当の鍵が無効になっている|必須|
            |s|サービスタイプ|該当の鍵が有効であるサービスを指定することができる<br>「,」で区切って複数指定をすることができる<br>指定できるサービスには「\*」(すべてのサービス)と「email」(電子メール)があり、省略時には「\*」が設定される|省略可能|
            |t|フラグ|フラグを指定する<br>コロンで区切ることで複数指定をすることができる<br>指定できるフラグは「y」と「s」がある<br>[y]<br>DKIMの運用が試験モードであることを示している。<br>このフラグが指定されている場合、受信者は認証の成功の可否にかかわらずメールを区別して処理してはならない<br>[s]<br>「DKIM-Signatureで指定されているiタグの@の後ろ」とz「DKIM-Signatureで指定されているdタグ」の値が一致する必要がある<br>省略時にはフラグ無し|省略可能|

- DKIMの公開鍵には以下の特徴がある
    - 鍵の長さは512ビットから2048ビットをサポートしている
    - 1024ビットより短い鍵はオフラインでの読解行為に対して脆弱である
    - 広範な普及を目指すために、鍵作成のコストを抑えることができるように考慮されている
        - DKIMの電子署名は第三者認証局が発行した電子証明書を利用せず、OpenSSLなどのツールを使って各ドメインの担当者が各鍵を作成する

# 送信者側の処理
## 送信者側の署名
- 送信者は、電子メールのヘッダおよびボディを元に電子署名を作成する
- 作成した電子署名を「DKIM-Signatureヘッダ」として追加する

    |タグ|タグの意味|説明|省略できるか|
    |---|---|---|---|
    |v|バージョン|バージョンを示す。現在は1のみ|必須|
    |a|署名作成に利用したアルゴリズム|アルゴリズムは以下のものがある<br>rsa-sha1<br>rsa-sha256|必須|
    |b|電子署名データ|電子署名のデータ。Base64にエンコードされている|必須|
    |bh|本文のハッシュ|本文をハッシュ化したもの|必須|
    |c|メール本文の正規表現方式|署名生成に利用する正規表現処理方法を指定。<br>"ヘッダ"/"本文"の正規表現に利用したアルゴリズムを記載する。**simple**と**relaxed**があるが後述する|省略可|
    |d|ドメイン名|署名をおこなったドメイン名|必須|
    |h|署名したヘッダ||必須|
    |i|認証対象になっている送信者のアドレス||省略可|
    |l|署名対象になっている本文の長さ||省略可|
    |q|公開鍵の取得方法||省略可|
    |s|セレクタ|公開鍵を取得するドメイン指定に使用する。複数セレクタを持つことで複数の公開鍵を使用できる|必須|
    |t|署名実施時のタイムスタンプ|署名を作成した日付。1970年からの秒数|利用を推奨（省略可）|
    |x|有効期限|署名の有効期限。有効である日時。1970年からの秒数。<br> **省略された場合は無期限になる**|利用を推奨（省略可）|
    |z|認証対象のヘッダコピー|動作テストで利用する。実際の確認処理では利用されない|省略可|

## 送信者側の処理
1. 署名の対象か確認する
    - gタグから今回送信するメールが署名の対象か確認をする
2. 署名対象のヘッダを決定し、hタグに列挙
2. メール本文をlタグに指定された長さ(指定が無ければ全文)取り出して正規化処理を実施する
    - 正規化処理にはsimpleとrelaxedがあり、simpleよりもrelaxedの方が配送中のメールデータ変更に寛容である
4. ヘッダ及び正規化したメール本文、これらを追加するDKIM-Signatureヘッダの署名データを除いた部分をつなげたデータに対してハッシュを作成
5. ハッシュに対して電子署名を作成し、DKIM-Signatureヘッダに追加したのちDKIM-Signatureをヘッダに追加する

## 受信側の処理
- 受信者側では、メッセージに付与されたDKIM-Signatureヘッダを取り出し、次の手順で署名の照合を行う
1. DKIM-Signatureヘッダのdタグ、sタグの値から、公開鍵を取得する
1. 先ほどのタグの値から鍵を取得する
    - iタグに設定してある@前がgタグの条件パターンに一致しない場合、署名の照合を行いません
3. hタグに記述されているヘッダと、メール本文のlタグに指定されている長さを切り出したもの、及び電子署名のデータ以外のDKIM-Signatureヘッダの値を合わせてハッシュの作成、電子署名の作成を行う
3. 作成したハッシュと受信したハッシュを比較し、同じであれば認証成功である

# DKIMの結果

 |値|	意味 |
 |---|---|
 |none|	 メールがDKIM署名されていない|
 |neutral|	 メールはDKIM署名されていたが、DKIM署名の文法上の誤りなどで、照合処理できなかった|
 |pass|	 メールはDKIM署名されており、署名の照合が成功し認証成功した|
 |policy|	 認証は成功したがローカルなポリシーによってその認証結果は受け入れられない|
 |hardfail|	 メールはDKIM署名されていたが、署名の照合が失敗し、認証が失敗した|
 |temperror|	 一時的な問題で認証処理を実行できなかった|
 |permerror	| 照合に必要なヘッダが存在しない場合など永続的なエラーで認証処理を実行できなかった|

 ## 調べた感想
SPFよりも設定値が多く，導入作業は少し大変かもしれないと思う
しかし，安全性は高いため導入するメリットは大きいと感じました．