HTTPSとTLSのしくみ
平文で流れているものを見てから始める
いま配信しているサイトは HTTP です。ブラウザとサーバーの間を、リクエストも応答もそのままの文字列で流れています。同じネットワークに居る誰かは、それを読めます。問い合わせフォームに書いた名前も、ログインのパスワードも同じです。
これを暗号化するのが HTTPS で、その中身が TLS という仕組みです。かつて SSL と呼ばれていたものの後継で、いまも習慣で SSL と呼ばれ続けています。設定項目の名前が ssl_ で始まるのはその名残です。
TLS が守るのは3つ
- 盗み見られない — 途中の誰かに中身が読めない
- 書き換えられない — 途中で改ざんされたら気づける
- 相手が本物だと分かる — 名乗っているサーバーが本当にそのサーバーである
見落とされがちなのが3番目です。暗号化だけなら鍵を交換すれば済みますが、それでは「暗号化された偽物」と通信してしまいます。本物かどうかを確かめる仕掛けが要ります。
証明書は、第三者の署名が付いた身分証
その仕掛けが証明書です。中身はこうなっています。
- どのドメイン名のためのものか
- 公開鍵
- 有効期限
- 誰が発行したか、そしてその発行者の署名
ブラウザは、あらかじめ信頼している発行者の一覧を持っています。届いた証明書の署名がその一覧の誰かのもので、名前も期限も合っていれば、本物と判断します。どれとも繋がらなければ警告を出します。
手元のマシンにも同じ一覧があります。
ls /etc/ssl/certs/ | headここに入っているのが、信頼の起点になる証明書です。
証明書の中身を読む
証明書はテキストのファイルですが、そのまま開いても意味不明な文字列が並ぶだけです。読める形に直すコマンドがあります。
openssl x509 -in <ファイル> -noout -subject -issuer -dates-noout は、元の暗号化された本体を出さない指定です。付けないと画面が文字列で埋まります。-subject が誰のためのものか、-issuer が誰が発行したか、-dates が有効期間です。
信頼の起点になる証明書では、subject と issuer が同じ値になっています。自分で自分を保証している、という形です。これが証明書の連なりのいちばん上で、ルート証明書と呼ばれます。
自己署名証明書とは何か
次の回で作るのは自己署名証明書です。自分で自分に署名した証明書で、いま見たルート証明書と形は同じです。違うのは、ブラウザの信頼する一覧に入っていないこと、それだけです。
だからブラウザは警告を出します。暗号化そのものは本物と同じ強さで効いていて、足りないのは「第三者が保証している」という部分だけです。
本番のサイトでは Let's Encrypt のような発行元から無料で正式な証明書を取れます。ただしそれには、外から届く本物のドメイン名が必要です。この学習環境には無いので、証明書を作って nginx に読ませ、暗号化された通信が成立するところまでを自分の手で通します。仕組みの理解に必要な部分は、これで全部触れます。
手を動かす
このマシンが信頼している証明書を1つ選び、中身を人が読める形にして保存します。