OREMATOPEE

プログラミング、気になったこと、メモ書き...etc

SSLを使った暗号化通信

参考

xtech.nikkei.com

まとめ

Lesson1

xtech.nikkei.com

SSLが持つ機能は大きく2つある。

  • データの暗号化
  • 通信相手が信頼できることの確認

クライアントからサーバへ「サーバ証明書」と呼ばれる情報を送り、それを検証することで信頼できるかどうか判断している。

SSLはアプリの種類を問わない汎用的なプロトコルなので、メールやFTPといったアプリケーションのデータを暗号化することも可能。

ブラウザは「http://」で始まるURLで指定したサーバに要求を送るときはTCPにデータを渡すが、「https://」宛の時はブラウザとTCPの間にSSLが間に入り、暗号化してからTCPに託す。
暗号データを受け取ったTCPはそれがSSLによるデータと示すため、443番ポートを介してIP、イーサネットに送り出す。
受信側であるTCPは443番ポートで受け取ると暗号データと解釈してSSLに託し、SSLが復号化を行ってからWebサーバへ情報が渡る。

SSLは元々ネットスケープ社が開発した独自仕様のプロトコルだったが、これをベースとしてTLSという標準技術が生まれた。
現在はTLS1.3が最新となっている。

Lesson2

xtech.nikkei.com

SSL共通鍵暗号公開鍵暗号の2つの暗号方式を使う。
しかし実際には、アプリケーション同士でやりとりするデータの暗号化には共通鍵暗号を使っているが、不特定なインターネットの通信では両者が通信前に同じ共通鍵を持つことはできない。

そこで前処理として公開鍵を利用する。
クライアントはSSL通信の要求を送り、サーバが秘密鍵と公開鍵のペアを生成し、自身の公開鍵が入ったサーバ証明書を送信し、クライアントはサーバ証明書をみて信頼できるか判断してその中からサーバの公開鍵を取り出して共通鍵を送る。
これにより以後は互いに共通鍵を使った通信が可能なのである。
(正確には共通鍵そのものをやりとりしているわけではなく、あくまでイメージ。後述)

Lesson3

xtech.nikkei.com

共通鍵を使って暗号通信を始めるまでにはさまざまなメッセージのやりとりがあり、これらを支えるSSLの仕様が大きく2つある。

  • レコード・プロトコル(メッセージのフォーマットを定義)
  • ハンドシェーク・プロトコル(やりとりの手順を定義)

SSLで運ぶメッセージはレコードと呼び、ヘッダ部とデータ部に分かれる。

ヘッダ部 データ部
データの種類(タイプ ハンドシェーク・プロトコルのメッセージ
バージョン(SSLTLSか) 暗号通信時の暗号データ
データ長

STEP2のSSLのやりとりを少し詳細に述べるなら、まず暗号通信時に使う暗号方式を決めるところから始まる。クライアントからサーバに暗号方式などの提案を行い、サーバはその中から適切なものを一つ選んで返答し、続けてCertificateメッセージを使ってサーバ証明書を送り、そのことを知らせる。
クライアントはこの証明書にある公開鍵を使って共通鍵を生成する元となる値、プレマスタシークレットを暗号化して送信する。
実際にはプレマスタシークレットを送るのであって共通鍵を送っているわけではないことに注意。
このプレマスタシークレットをサーバは自身の秘密鍵で復号すると共通鍵が生成されるというしくみ。

共通鍵のやりとりはClientKeyExchangeメッセージによって実現されている。
あとは互いに暗号方式の採用を宣言して、ハンドシェークの終了を互いに知らせる。
ここまでがハンドシェークの一連の流れ。

Lesson4

xtech.nikkei.com

サーバ証明書認証局と呼ばれる組織に申請して発行してもらう。
この証明書は認証局秘密鍵で暗号化されていて、この発行された証明書をサーバがクライアントに渡して、クライアント側で認証局の公開鍵を使って復元できれば、認証局の証明書だとわかる仕組み。

証明書の内容
サーバ運営者の組織名
認証局の組織名
証明書の有効期限
サーバの公開鍵

※証明書には認証局の署名がついている。

認証局自体が信頼できるのか?

実は、サーバ証明書とともに認証局の証明書もクライアントに送られていて、もしその認証局が他の認証局から署名を受けている場合はその署名を書いた認証局の証明書も送られる。最終的には上位のルート認証局が必ずついてきて、まずはそのルート認証局が信頼できるのかをクライアントは確認する。
PCには元からルート認証局の証明書が入っていて、送られてきた証明書と一致しているかで信頼性を判断している。信頼できるとなれば上位から下位に向かって認証局の証明書を検証する。

クライアントはこのルート認証局の証明書にある公開鍵を使って、サーバー証明書の署名を復号したデータとサーバー証明書のハッシュを調べて一致すれば、ルート証明局から署名を受けたサーバー証明書であることがわかる。