HTTPSの鍵渡しパズル — 盗聴者の前で南京錠を配る
URLの横の鍵マーク🔒。あれは「この通信は暗号化されています」の印ですが、よく考えると不思議です。暗号でやりとりするには、まず2人が同じ鍵を持つ必要があります。でもその鍵自体は、盗聴者が見ている道を通して渡すしかない。鍵を送れば盗聴者にもコピーされてしまうのに、どうやって?
この「鍵を安全に渡すパズル」を解くのがTLSハンドシェイクです。種明かしは「開いた南京錠を先に送る」という発想の転換。下の図1で、盗聴者の反応を見ながら順に追ってみてください。
なぜ「南京錠」で解決するのか
図1の主役は、サーバーが配った開いた南京錠=公開鍵です。南京錠の面白い性質は、閉めるのは誰でもできるが、開けられるのは合鍵(秘密鍵)を持つ本人だけということ。だから南京錠そのものは盗聴者に見られても、コピーされてもかまいません。盗聴者が手に入れたのは「閉める道具」だけで、「開ける道具」は一度も道を通っていないからです。
では最初から全部の通信を南京錠方式(公開鍵暗号)でやればよさそうですが、そうしないのには理由があります。公開鍵暗号は計算がとても重く、共通鍵暗号の数百〜数千倍遅いのです。そこで実際のTLSは「重い南京錠は最初の鍵渡しだけに使い、あとは軽い共通鍵で高速にやりとりする」という分業をします。配達は一瞬、でも入口の儀式だけは厳重に — の使い分けです。
もう1つの落とし穴が、ステップ4で確認した証明書です。もし盗聴者が「私がサーバーですよ」と偽の南京錠を送ってきたら、暗号化しても無意味になってしまいます(中間者攻撃)。だから南京錠には、信頼できる第三者機関(認証局)の署名つき保証書が添えられていて、ブラウザはそれを必ず検査します。保証書が怪しいときに出るのが、あの「この接続ではプライバシーが保護されません」という警告画面です。
- 公開鍵 / 秘密鍵
- 開いた南京錠と、その合鍵。南京錠は配ってよいが、合鍵は本人だけが持つ。
- 共通鍵
- 閉めるのも開けるのも同じ1本の鍵。高速だが、渡し方に工夫がいる。
- 証明書(CA)
- 「この南京錠は本物のサーバーのものです」という認証局の署名つき保証書。
まとめ
TLSハンドシェイクの核心は3つ — 南京錠(公開鍵)は見られてもよい、保証書(証明書)で本物か確かめる、渡し終えたら軽い共通鍵に切り替える。URLの鍵マークは「この儀式が無事に済みました」の印だったのです。次にあのマークを見たら、裏で南京錠が一往復したことを思い出してみてください。