SSLサーバ証明書の仕組み

定期的に細部を忘れるので,備忘としてメモしておくことにした.
上述の目的なので,自分にわかる粒度で書いてます.
「初歩すぎだろ」って箇所も多々ありますがご容赦を.

まずは2つの前提知識

(1) 公開鍵暗号
公開鍵と秘密鍵のペアを使う暗号化方式を用いる
これらの鍵には特殊な性質があって,
秘密鍵で暗号化した情報は公開鍵でしか解読できない
・公開鍵で暗号化した情報は秘密鍵でしか解読できない
の2つを有する.
秘密鍵を,名前のとおり秘密にしておく形となる.
公開鍵は,名前のとおり公開されていて,誰でもゲットできる.

(2) 電子署名
これは上述の前者の性質を使う.
たとえば
"NK5から山田太郎さんへ……2018/11/24の18時に署名"
という文字列を,
俺が持っている秘密鍵で特定のアルゴリズムで暗号化することで,
"jiewaofawietjaieaow"
という文字列が出来上がる(文字列自体は適当).
有り体に言えばこれが署名.

この文字列は,前述の公開鍵を用いることでのみ,
"NK5から山田太郎さんへ……2018/11/24の18時に署名"
に復号化される.
ほかの公開鍵を用いても,別の意味不明な文字列に変換される.
この論理により,
「なるほど,この署名は間違いなくNK5が作ったものだな!」
と,この署名の正当性が保証される.

なお,署名(上記の例だと"jiewaofawietjaieaow")が
悪意のある他人に流用されても大丈夫なように
暗号前の平文に何かしらの工夫を施す.
例えば上記の場合は,宛先と署名日時を平文に含めているので,
後日犯罪者に流用されたとしても,復号化した時点で
「あれ?日付が違うぞ……?」
と気づくような感じ.実際は違うんだけどあくまでイメージとして.


で,本題に戻ると,
サーバ(鯖男とする)とクライアント(倉子とする)は
安全な通信を実現するために,
お互いだけが知る「合言葉」を共有する必要がある.

当然その合言葉はバレてはいけないので,鯖男は倉子に
「俺の公開鍵を使って,その合言葉を暗号化してよ」
と,公開鍵を渡しつつ申し出るわけである.

が,このやり方には1つ問題がある.
鯖男から倉子に鍵が渡されるまでのバトンリレーの途中で
悪意のある人が鍵をすり替える可能性がある.

そこで,鯖男は公開鍵だけでなく,「デジタル証明書」を送り付ける.
デジタル証明書にはこう書いてある.
「これは間違いなく鯖男氏の公開鍵です 認証局Aより」
ここに前述のデジタル署名が付与されているので,
倉子は認証局Aの公開鍵を用いることで,その正当性を検証できる.

が,倉子が慎重な性格であれば,
「この認証局Aの公開鍵が本物である保証はどこに……」
という,当然の疑問に行き着く.
ここで
「これは間違いなく認証局Aの公開鍵です 認証局Bより」
という別の証明書が登場するわけだが,
じゃあこの認証局Bの公開鍵は……という,無限ループに陥る.

で,最終的にこの連鎖を止めるために
「これは間違いなく俺の公開鍵です 俺より」
という,自己完結型の「ルート証明書自己署名証明書)」が登場する.
これの作成を許されるのは社会的に認められた組織(ルート認証局)のみで,
各ブラウザに標準でインストールされていたりする.
このルート証明書&公開鍵を基点とすることで,信頼の連鎖が成立する.

たとえば,認証局Bの公開鍵が
「これは間違いなく認証局Bの公開鍵です ルート認証局Xより」
という感じで保証されていれば,信頼の連鎖が成り立つわけだ.

ちなみに社会的に認められていない組織が作った自己署名証明書
一般に「オレオレ証明書」と呼ぶ.

ともあれ,倉子はこの証明書を検証することで,
「よし,これは間違いなく鯖男の公開鍵だな!」
と確信し,合言葉を暗号化して鯖男に送りつける.
復号化できるのは鯖男だけなので,無事にお互いだけが合言葉を共有できる.
以後はこの合言葉を使って秘密のやり取りを開始する.


という感じ,で,合ってるはず.