HTTPSとTLSのしくみ

平文で流れているものを見てから始める

いま配信しているサイトは HTTP です。ブラウザとサーバーの間を、リクエストも応答もそのままの文字列で流れています。同じネットワークに居る誰かは、それを読めます。問い合わせフォームに書いた名前も、ログインのパスワードも同じです。

これを暗号化するのが HTTPS で、その中身が TLS という仕組みです。かつて SSL と呼ばれていたものの後継で、いまも習慣で SSL と呼ばれ続けています。設定項目の名前が ssl_ で始まるのはその名残です。

TLS が守るのは3つ

  1. 盗み見られない — 途中の誰かに中身が読めない
  2. 書き換えられない — 途中で改ざんされたら気づける
  3. 相手が本物だと分かる — 名乗っているサーバーが本当にそのサーバーである

見落とされがちなのが3番目です。暗号化だけなら鍵を交換すれば済みますが、それでは「暗号化された偽物」と通信してしまいます。本物かどうかを確かめる仕掛けが要ります。

証明書は、第三者の署名が付いた身分証

その仕掛けが証明書です。中身はこうなっています。

  • どのドメイン名のためのものか
  • 公開鍵
  • 有効期限
  • 誰が発行したか、そしてその発行者の署名

ブラウザは、あらかじめ信頼している発行者の一覧を持っています。届いた証明書の署名がその一覧の誰かのもので、名前も期限も合っていれば、本物と判断します。どれとも繋がらなければ警告を出します。

手元のマシンにも同じ一覧があります。

ls /etc/ssl/certs/ | head

ここに入っているのが、信頼の起点になる証明書です。

証明書の中身を読む

証明書はテキストのファイルですが、そのまま開いても意味不明な文字列が並ぶだけです。読める形に直すコマンドがあります。

openssl x509 -in <ファイル> -noout -subject -issuer -dates

-noout は、元の暗号化された本体を出さない指定です。付けないと画面が文字列で埋まります。-subject が誰のためのものか、-issuer が誰が発行したか、-dates が有効期間です。

信頼の起点になる証明書では、subjectissuer が同じ値になっています。自分で自分を保証している、という形です。これが証明書の連なりのいちばん上で、ルート証明書と呼ばれます。

自己署名証明書とは何か

次の回で作るのは自己署名証明書です。自分で自分に署名した証明書で、いま見たルート証明書と形は同じです。違うのは、ブラウザの信頼する一覧に入っていないこと、それだけです。

だからブラウザは警告を出します。暗号化そのものは本物と同じ強さで効いていて、足りないのは「第三者が保証している」という部分だけです。

本番のサイトでは Let's Encrypt のような発行元から無料で正式な証明書を取れます。ただしそれには、外から届く本物のドメイン名が必要です。この学習環境には無いので、証明書を作って nginx に読ませ、暗号化された通信が成立するところまでを自分の手で通します。仕組みの理解に必要な部分は、これで全部触れます。

手を動かす

このマシンが信頼している証明書を1つ選び、中身を人が読める形にして保存します。

ヒント

  • 1. ls /etc/ssl/certs/ で並んでいる証明書を見る
  • 2. その中から1つ選ぶ
  • 3. openssl x509 -in <ファイル> -noout -subject -issuer -dates を打つ
  • 4. 出力を /root/root-cert.txt に保存する
  • 5. subject と issuer を見比べ、同じなら same、違うなら different と /root/is-root.txt に書く

7 項目で採点します