フィンガープリント、認証、署名、証明書、SSL/TLSってどんな関係だっけ？

ってなったときにざっくり思い出す用の記事です。

# 各用語の簡単な説明

|名称|説明|
|---|---|
|暗号化|メッセージを第三者に理解できない暗号文にすること。機密性を担保する。|
|認証|メッセージが本当に通信したい相手からのものであることを確かめること。|
|フィンガープリント|一方向ハッシュ関数の出力であるハッシュ値のこと。メッセージダイジェストとも。ソフトウェアの作者がハッシュ値を公開し、利用者が手に入れたソフトウェアのハッシュ値と、作者のハッシュ値が一致するか確かめることでソフトウェアの改ざん検知をすることができる。|
|署名(デジタル署名)|メッセージのハッシュ値を暗号化した暗号文。その暗号文はメッセージの作成者しか作ることができないので、「このメッセージは〇〇が作りました」と証明することができる。この暗号文は第三者が解読できる（メッセージの作成者を証明するだけ。機密性は守られない）。解読用の公開鍵が〇〇さんのもであることの証明はないので中間者攻撃ができてしまう。|
|証明書(公開鍵証明書)|認証局に登録された公開鍵と、それに対する認証局のデジタル署名をセットにしたもの。デジタル署名を検証するための公開鍵は更に他の認証局によって証明書が発行されており、その繰り返しになっている。証明書のデジタル署名を検証するには、その連なる証明書すべてを検証する必要がある。認証局によって「この公開鍵は確かに〇〇さんのものである」と認められているので中間者攻撃に耐性がある。|
|SSL/TLS|対称暗号、公開鍵暗号、デジタル署名、一方向ハッシュ関数などの技術を組み合わせて暗号通信を実現するフレームワーク。HTTPだけでなく、SMTPなどの他のプロトコルもそのフレームワークに乗せて暗号通信を実現できる。|

# 各技術が持つ効果

|名称|機密性|改ざん検知(正真性、完全性)|否認防止(メッセージの送信者を第三者に証明できること)|認証|中間者攻撃耐性|
|---|---|---|---|---|---|
|対称暗号|○|-|-|-|-|
|公開鍵暗号|○|-|-|-|-|
|一方向ハッシュ関数|-|○|-|-|-|
|メッセージ認証コード|-|○|-|○|-|
|署名|-|○|○|○|-|
|証明書|-|○|○|○|○|
|SSL/TLS|○|○|○|○|○|
SSL/TLSは上記全部を組み合わせて使うのでこうなる

# 各用語のもう少し詳しい説明
## 対称暗号
暗号化と復号化に同じ鍵を用いる暗号化方式。
公開鍵暗号よりも処理速度が早いが、通信相手にどうやって鍵を安全に渡すかが問題となる。

## 公開鍵暗号
暗号化と復号化で異なる鍵を用いる暗号化方式。
送信者は公開鍵でメッセージを暗号化し、受信者は秘密鍵で復号化する。
公開鍵は第三者が持っていても復号化には利用できない。
受信者は公開鍵を送信者に好きな方法で渡せば良いため、鍵配送問題が解決する。
しかし、送信者が、受信者になりすました攻撃者から公開鍵を受け取って暗号化してしまうと、攻撃者によってメッセージを復号化されてしまう中間者攻撃が可能。

## 一方向ハッシュ関数
メッセージを入力にして固定ビット長のハッシュ値を計算して出力する処理。
ハッシュ値から元のメッセージを復元することは困難であるため、送信者はメッセージと一緒にハッシュ値を送り、受信者がメッセージからハッシュ値を計算して送られてきたハッシュ値と比較することでメッセージが改ざんされていないこと（正真性）を確かめることができる。
ハッシュ値はフィンガープリントとも呼ばれる。
あくまでメッセージが改ざんされていないことが保証されるだけで、"正しい送信者からの"メッセージであることは保証されないので認証には使えない。

## メッセージ認証コード  
送信者と受信者で共有する鍵とメッセージとを入力として、一方向ハッシュ関数により固定ビット長の出力値（message authentication code: MAC値）を計算する処理。
共有鍵を持っているのは正しい通信相手だけで、しかも鍵とメッセージから一方向ハッシュ関数を使って求められたMAC値は、受信者も鍵を持っているため計算して検証が可能。
つまり認証と改ざん検知が可能。
しかし、第三者からすると共有鍵を持つAさんBさんのうち、どちらが作ったメッセージかわからないため、Aさんが第三者に「Bさんが100万を私に支払うというメッセージを送ってきました」と言っても、Bさんが「私はそんなの送ってない。そのメッセージはAさんが作ったものだ」と言って否定できてしまう。
つまりメッセージ認証コードでは否認防止はできない。

## デジタル署名
送信者が秘密鍵でメッセージを暗号化した暗号文のこと（公開鍵暗号とは逆であることに注目）。
受信者は公開鍵でその暗号文を復号化するが、公開鍵なので第三者でも復号化ができる。
署名用の鍵（秘密鍵）は送信者だけが持ち、検証用の鍵（公開鍵）は誰が持っていても良い。
送信者は署名用の鍵でメッセージを暗号化（この暗号文が署名）し、受信者は検証用の鍵で復号化する。
メッセージを暗号化できるのは秘密鍵を持つ送信者本人のはずだし、検証用の鍵は誰が持ってもいいので第三者がメッセージを復号化して「このメッセージはAさんがくれた検証用の鍵で復号化できたので、確かにAさんが送ったものである」と確かめることができる。
長くなる可能性のあるメッセージに署名すると公開鍵暗号のアルゴリズムでは処理に時間がかかるので、実際にはメッセージのハッシュ値に署名をする。
秘密鍵を持つのは正しい送信者ただ一人であることと、ハッシュ値を使うことで、認証、改ざん検知、否認防止を実現できる。
ただし、第三者でも復号化ができるのでこれは機密性を守るものではない。
また、公開鍵暗号と同様に中間者攻撃が問題となるため、次に説明する証明書で公開鍵が正しい相手のものか確かめる必要がある。


## 公開鍵証明書
認証局に登録している人が所有している公開鍵と、認証局によるデジタル署名のセット。
この公開鍵を使いたい人は認証局の公開鍵でこの署名を検証（復号化）することで使用したい公開鍵が正しいものであることを確認できる。
この認証局の公開鍵もまた、正しい公開鍵であることが求められるので、他の認証局によって証明書が発行されている。
その認証局の署名もまた検証するためにさらに他の認証局によって証明書が～と、いった具合に連鎖している。
この連鎖のもとをルートCAという。ルートCAは自分で自分の証明書を作る。ルート証明書の鍵が手に入らないと使いたい鍵の検証ができない。

## SSL/TLS
暗号通信のためのフレームワーク。
HTTPだけでなく、SMTPやPOP3などの他のプロトコルを乗せることも可能。
暗号通信を実現するためにこれまで紹介した各技術を使うが、それら技術のアルゴリズムは交換可能になっている（アプリケーションフレームワークを構成するライブラリを交換するイメージ）。
機密性の担保に対称暗号、対称暗号は擬似乱数生成器で鍵を生成。鍵の配送は公開鍵暗号またはDiffie-Hellman鍵交換。改ざん検知と認証にメッセージ認証コード。メッセージ認証コードは一方向ハッシュ関数を使って構成。通信相手の認証は、認証局によるデジタル署名を含む公開鍵証明書を使う。

#### HTTPSでの証明書のやりとり
1. サーバがクライアントに証明書リスト（そのサーバのものから始まりその証明書に署名している認証局の証明書が順番に続く）を送信する
2. クライアントはサーバから送られてきた証明書を検証する
3. サーバはクライアントを認証するためにクライアントに証明書を要求する
4. クライアントは証明書をサーバに送り、サーバは証明書を検証する。