戻る

TLS、クライアント証明書、TOFU、その他もろもろ

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

はじめに

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

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

 鍵ペア、つまり1組の公開鍵と秘密鍵は、一方を使って暗号化されたものは他方でしか復号化できない、という性質を持ちます。
 デジタル署名とは、人々が自分の秘密鍵を使ってデジタルコンテンツに「署名」し、それを他の人が自分の公開鍵を使って検証できるというもので、署名は偽造できず、署名されたコンテンツは改ざんから保護されるというものです。

証明書の基本

 TLS証明書とは何でしょうか?
 TLS証明書とは、以下のものを組み合わせたものと考えてください。

・公開鍵
・公開鍵の所有者とされる人物に関するいくつかのメタデータ……証明書の「サブジェクト」と呼ばれます。
・証明書全体に対するデジタル署名
・証明書に署名した当事者に関するメタデータ……証明書の「発行者」と呼ばれます。
・有効期限

 サブジェクトと発行者のメタデータは同じ構造を持っています。このように、証明書にはサブジェクトと発行者の「識別名」(DN)が含まれます。DNには複数のフィールドがありますが、最も重要なのはいわゆる「Common Name」(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 証明書が果たす *役割* について考えてみると、ある当事者 (発行者) が他の当事者の主張 (「この鍵は私のもの」という Subject の主張) の正当性を、発行者と既存の信頼関係にある人 (発行者の公開鍵を持ち、したがってそのデジタル署名を検証できる) を納得させる方法で保証する手段であることがわかります。

 では、CAシステムでこの「中間者」(MitM)の問題は解決されるのですか?
 まあ、イエスでもありノーでもあります。

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

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

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

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

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

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

 鍵が本当にそのホスト名に属していることを他の手段で証明できる場合、 または
 鍵の所有者を確認することは、実際には重要ではありません。
 自己署名入り証明書は、完全に有効な手段です。

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

クライアント証明書

もうすぐです。

TOFU

近日公開

実用的な質問

近日公開

(原典)gemini://gemini.circumlunar.space/docs/tls-tutorial.gmi
(2022年12月13日 初版)

戻る