TLS、クライアント認証、TOFUなどなど

このドキュメントは作成中です!

イントロダクション

Geminiは、TLSを用いた接続の保護を必須としています。 それだけでなく、クライアント証明書の使用や、その代替となる、多くの人にとって馴染みのない証明書検証スキームもサポートしています。 Geminiの開発者になろうとする多くの人にとって、これは最も困難な部分です。 このドキュメントは、関連する概念について優しく紹介することを目的としています。 このドキュメントの目標は、暗号の詳細よりも抽象的なレベルで、このようなものがどのように機能するかを理解し、推論できるようにすることです。

この文書は、完全に「ゼロから」説明するものではありません。 この文書では、あなたが非対称暗号(または「公開鍵」)の基本的な概念に精通していることを前提にしています。 基本的には、以下のような考え方に慣れている必要があります。

認証の基本

TLS認証とは?

ここでは、TLS証明書を以下の組み合わせと考えることができます。

サブジェクトと発行者のメタデータは同じ構造を持っています。 証明書には、サブジェクトと発行者の「識別名」(DN)が含まれます。 DNには複数のフィールドがありますが、最も重要なのはいわゆる「コモンネーム」(CN)と呼ばれるものです。 CNは必ずしもそうである必要はありませんが、典型的な実世界での使用では、サブジェクトのCNはほとんど常に `paypal.com` のようなホスト名です。

証明書にはこれ以上のものがあることもあり、また実際にはよくあることですが、 この記事の続きを読むには、これらの核となる機能を理解する必要があります。 多くの場合、有効期限のことは忘れて、証明書を公開鍵、それを所有すると主張する人の名前、そしてその主張が真実であると証明する人(それゆえに証明書という名前なのです!)の名前と署名として考えることができます。

TLS証明書は一般的にどのように使用されますか?

あなたが `example.com` という名前のサーバーの正当なオペレータだとします。 TLS を使用する「通常の」方法は、「認証局」(CA)と呼ばれる信頼できるサードパーティに連絡して、「こんにちは、CAさん、私のDNはbla, bla, blaで、特にCNはexample.comです。 このバイトの塊は私の公開鍵です」と言います。 CAは、あなたが本当にexample.comの正当な運営者であると確信するために「何か」を行い、その秘密鍵を使って、あなたのDN(サブジェクトとして)、自分のDN(発行者として)、および有効期限を特徴とする証明書に署名するのです。 そして、ウェブサーバーやメールサーバーなど、クライアントがTLS証明書を発行するときにその証明書を渡すように設定します。

クライアント側では、ウェブブラウザやオペレーティングシステムには、通常、認識されたCAの公開鍵が大量にプリインストールされています。 誰かがあなたのウェブサーバーに接続し、あなたの証明書を取得すると、彼らはあなたのCAのDNを使って、そのCAの公開鍵を山の中から見つけ、そしてあなたの証明書の署名を検証することができるのです。 署名が有効であれば、その証明書の公開鍵が本当に example.com のものであると確信するために、その立派で立派な CA が何かをしたのだということが伝わります。 クライアントはCAを信頼しているので、この公開鍵が本物であることを受け入れ、(有効期限が過ぎていないと仮定して)すべてがうまくいきます。クライアントとサーバーは認証された公開鍵を使って、実際には証明書とはほとんど関係のない複雑なプロセスを経て、安全なチャンネルを立ち上げるのです。

なぜこのようなことが必要なのですか?

クライアントが example.com に接続するとき、サーバーが証明書の代わりに素の公開鍵を送信したとします。 クライアントはその鍵を使ってサーバーに送信する情報を暗号化することができ、その情報は盗聴者から安全に保護されます。 このリスクは、接続を盗聴できるだけでなく、より積極的な方法で干渉できる誰か、たとえばクライアントやサーバの ISP、あるいはクライアントの DNS プロバイダを騙して example.com を自分のサーバに解決させた誰かがいわゆる「中間者」(MitM)として行動できる可能性があることです。 クライアントがサーバーに接続しようとすると、攻撃者は代わりに自分の公開鍵をクライアントに送り返します。 同時に、意図したサーバーに接続し、サーバーの実際の公開鍵を受け取ります。 攻撃者は、クライアントから受け取ったものを自分の秘密鍵で復号化し、サーバの公開鍵で再暗号化してからサーバに送信します(逆方向の場合も同様)。 クライアントとサーバーは互いに会話することができ、すべてが機能しているように見えますが、クライアントとサーバーがすべてを暗号化したにもかかわらず、攻撃者はすべてを読むことができるのです。

これを防ぐには、クライアントが、接続を傍受して自分の鍵をすり替えた攻撃者ではなく、送られてくる公開鍵が本当に example.com のものであることを知る必要があります。 これは非常に難しい問題です。 多くの解決策があり、それぞれに長所と短所があります。 現在のインターネットでは、CAが署名した証明書を使用するのが主流です。 これは基本的に、誰がどの公開鍵を本当に所有しているかを確認するという難しい仕事を、少数の(インターネット上のコンピュータの数に比べて)信頼できる当事者(CA)に委託するもので、CAはこの仕事をうまくこなすことが期待されています。

したがって、TLS証明書の中身やコンピュータが何をするかという技術的な詳細から離れ、代わりにTLS証明書が果たす「役割」という観点から考えてみると、TLS認証は、ある当事者(発行者)が他の当事者の主張(「この鍵は私のもの」という被写体の主張)の正当性を、発行者と既存の信頼関係にある人(発行者の公開鍵を持ち、したがってそのデジタル署名を検証することができる)を納得させられる方法で保証するための一つの手段であることがわかるでしょう。

なるほど、CAシステムでこのMitMの問題は解決されるのですね?

えー、YesでありNoです。

CAシステムによって提供されるセキュリティにあまり満足していない人もいます。 上に述べた単純な検証手順の上にたくさんの余分なものを積み重ねない限り、ブラウザやオペレーティングシステムにあらかじめインストールされている公開鍵を持つ *任意の* CA は *任意の* ホスト名の証明書に署名でき、あなたのシステムは喜んでそれを受け入れることでしょう。 世界中の企業や政府が所有する、文字通り何百ものCAのリストがあり、その信頼度は実にさまざまです(現実的には、その大半について聞いたこともなければ、以前に接したこともないでしょう)。 公開鍵を所有しているという主張を最も注意深くチェックしない認証局、インターネットセキュリティが最悪で秘密鍵を盗まれた認証局、最も簡単に買収される従業員を抱える認証局、政府が最も法的権限を持ち、刑務所やそれ以上の脅しで偽の証明書に署名させた認証局、などです。 最も弱いCAは本当に弱いかもしれませんし、あるCAが「不正になった」ことが発見された場合、そのCAがインストールされていた各デバイスからその公開鍵を削除するのは大変な作業で、多くの時間がかかるでしょう。

CAシステムが提供するセキュリティにはあまり関心がなく、むしろ政治的、哲学的な理由から、システム全体が主に比較的少数の民間営利企業が高価な集中型インフラを運営し、エンドユーザーに証明書の対価として(時には多額の)お金を請求することに不満を持っている人もいます。

自己発行証明書、自己署名証明書とは何ですか?

証明書は、サブジェクトと発行者が同一であれば「自己発行」され、証明書に含まれる公開鍵に対応する秘密鍵を用いて署名されていれば「自己署名」されます。 証明書は自己署名されていなくても自己発行されることがあり、またその逆もありますが、最も一般的なケース(そして「自己署名証明書」について話すときにほとんどの人が考えているケース)は、証明書がこれらの両方の性質を持つということです。

自己署名証明書は、証明書の一般的な使用方法と互換性がありません。クライアントがすでに信頼し、サーバーが自分自身を認証しているCAのような第三者が存在しないため、公開鍵の所有者に対する信頼を確立する方法として機能しません。 自己署名証明書は、誰でも好きなサブジェクトCNで作ることができます。 もしあなたがサーバに自己署名証明書を使うなら、クライアントはそれを攻撃者がMitM攻撃のために作ったものと区別することはできません。少なくとも、証明書を見て署名を検証するだけではね。 これが、自己署名証明書が安全でないと一般に考えられている理由です。

これは小さな問題ではありませんが、自己署名証明書とCA署名証明書の違いは、含まれている公開鍵が本当に含まれているホスト名に属していることを、証明書自体を調べるだけで立証できるかどうかという問題であることを理解しておくことが重要です。 含まれる公開鍵自体は、CA署名入り証明書の公開鍵と何ら変わりはなく、劣ることもありませんし、その鍵を使った暗号の強度にも差はありません。 つまり、以下のような状況です。

自己署名入り証明書は、完全に有効なものです。

単に公開鍵を使うのではなく、自己署名証明書を使うことにどんな価値があるのでしょうか? 実は、ほとんどありませんというのが答えです。証明書なしで裸の公開鍵を使用する安全なプロトコルはたくさんあります。 しかし、TLS は完全に CA 署名入り証明書の概念に基づいて構築されており、公開鍵を単独で使用する方法は提供されていません。 自己署名証明書は、この問題を回避するためのハックと考えることができます。

クライアント認証

近日公開

TOFU

近日公開

実用上の質問

近日公開