TLSハンドシェイク

ハンドシェイクプロトコルにより,サーバーとクライアントは暗号化された通信路を確立することができます。つまり,通信ができるようになるのはハンドシェイクが完了した後ということになり,「接続できない」という問題が生じるのはハンドシェイクの部分だということになります。ここの仕組みが分かれば,「HTTPSを(接続トラブルが起こる部分だけ)理解した」と言えるでしょう(一般的な使用方法においては,これくらいの理解で十分でしょう)。
ハンドシェイクの主なやりとりは,以下のとおりです。

  1. クライアントからサーバにClientHelloが送られ,サーバからクライアントにServerHelloと鍵共有に必要な情報が送られる。
  2. クライアントからサーバに鍵共有に必要な情報が送られる。
  3. クライアントからサーバに暗号化されたFinishedが送られ,サーバからクライアントにも暗号化されたFinishedが送られる。
  4. 暗号化されたデータ通信の開始。

要は,鍵交換を行って,データ通信ができるかの確認をしているだけです。
公開鍵暗号の仕組みは周知であると思われますので,説明は省略します。
接続で問題となるのは,鍵共有に必要な情報としてサーバからクライアントに送られる「証明書」です。この証明書から何が取り出されるのか,それがどのように使われるのか,詳しく見ていきたいと思います。

サーバ証明書

証明書は,通常,X.509v3のものが使われます(X.509という規格の第3版)。
この証明書の符号化形式(拡張子)にはいろいろありますが,ちゃんと意味はあるようです(cerはCERで符号化されたもの,pemはBase64で符号化されたもの,など)。もっとも,プログラム側でファイルの内容からフォーマットを確認しているようなので,拡張子はなんでもいいのかもしれません。
証明書の中には,「発行者」と「主体者」の情報が格納されているほか,「主体者の公開鍵」も含まれており,最後に「(発行者の)署名」が含まれています。
「(発行者の)署名」は,証明書に書かれている内容のハッシュ値を,発行者の秘密鍵で暗号化したものです。証明書を受け取った人は,公開鍵を使って署名を復号し,受け取った証明書情報から計算されるハッシュ値と比較します。これが一致すれば,この証明書は正しく発行者が作成したものであると確認されるわけです。