このシリーズについて
この記事は「OpenSSLでプライベートCAを作る(全15章)」の一部である。章番号はシリーズ全体で通し番号になっている。はじめに・開発環境・まとめ・参考文献は目次記事にある。
2. 基本概念
2.1. TLS(Transport Layer Security)
TLSとは、インターネットなどのIPネットワークでデータを暗号化して送受信するプロトコル(通信手段)の一つ。送受信データの暗号化による盗み見の防止、相手方の認証による真正性の確認(なりすまし防止)、経路途上での改竄検知などを行うことができる。
(「IT用語辞書_TLS」より引用)
2.2. mTLS
mTLSとは、WebサーバとWebクライアント(ブラウザなど)の間で認証と暗号化を行うTLSの拡張仕様の一つで、サーバとクライアントが互いに相手をデジタル証明書によって認証すること。
(「IT用語辞書_mTLS」より引用)
なお、この引用では「TLSの拡張仕様」とあるが、クライアント認証はTLS本体の仕様に含まれる機能である(RFC 8446 §4.3.2)。詳しくはG01. mTLSの"m"とはを参照。
普段HTTPSでアクセスするとき、身元を証明しているのはサーバのみである。
クライアント(ブラウザ) ─── HTTPS ─── サーバ(example.com)
│
「私は example.com です」 ◀───────────┘
↑ サーバだけが証明書を出す
「あなたは誰ですか?」 ──✕──▶
↑ クライアントは聞かれない
mTLSでは、これが双方向となる。
クライアント(端末) ─── HTTPS ─── サーバ(example.com)
│
「私は example.com です」 ◀────────────┘
↑ サーバが証明書を出す
「私は device-001 です」 ────────────▶
↑ クライアントも証明書を出す
用語解説(別記事)
2.2.1. mTLSの利点
-
アプリケーションに届く前に弾ける
- 許可されていない端末からのリクエストは、HTTPのリクエストとして解釈される前に切断される
- Webアプリの脆弱性を突く攻撃も、そもそも到達しない
-
秘密鍵がネットワークを流れない
- パスワードは「知っていること」を送って証明するが、証明書は「持っていること」を送らずに証明する
- 経路上で盗聴されても、認証に必要な情報は手に入らない
2.2.2. パスワード認証との違い
通常認証ではIDやパスワードを利用するが、次のような違いがある。
| ID/パスワード、APIキー | クライアント証明書(mTLS) | |
|---|---|---|
| 認証の層 | アプリケーション層 (HTTP) |
トランスポート層 (TLS) |
| 認証される対象 | 人・アカウント | 端末・機器 |
| いつ検証されるか | リクエストが届いた後 | TLSハンドシェイク中 (通信が始まる前) |
| 秘密情報の送信 | パスワードを送る | 秘密鍵は送らない |
| 漏れたときの再発行 | パスワード変更 | 証明書を失効させて再発行 |
2.2.3 mTLSのハンドシェイク
TLS 1.3のハンドシェイクは次の流れになる(RFC 8446 §2 のFigure 1に対応)。
用語解説(別記事)
通常のHTTPSには現れないメッセージが3つある。図では背景に色を付けてある。
| メッセージ | 送る側 | 役割 |
|---|---|---|
CertificateRequest |
サーバ | 「このCAが発行した証明書を出してください」とクライアントに要求する |
Certificate |
クライアント | クライアント証明書を出す |
CertificateVerify |
クライアント | 秘密鍵で署名し、その証明書の持ち主であることを示す |
CertificateとCertificateVerifyはサーバも送っている。色が付いているのは、そのうちクライアントが送るほうである。通常のHTTPSに現れるのはサーバが送る2つだけで、mTLSではクライアント側の2つと、それを要求するCertificateRequestが加わる。
CertificateRequestがサーバのCertificateより前に来る点に注意。先に「証明書を出してください」と依頼してから、自分の証明書を送る順序になっている。
用語解説(別記事)
2.2.4. mTLSが適する場面・不適な場面
端末に証明書を配る手間が存在するため、適する場面と適さない場面がある。
適する場面
- 端末の台数が限られていて、管理下にある
- 例:社給端末、店舗のタブレット、IoT機器
- サービス間通信
- 例:マイクロサービス、社内API
- 「人」ではなく「機器」を認証したい
適さない場面
- 不特定多数の一般利用者が使うWebサイト
- 全員に証明書を配ることが現実的でない
- 端末が頻繁に入れ替わる
- 発行・失効の運用コストが利益を上回る
- 「誰が操作したか」を特定したい
- 証明書が認証するのは端末であって人ではない
- 端末を共有すれば区別できない。人の認証が要るなら別途ログインを併用する
2.3. ハイブリッド暗号方式と公開鍵証明書
TLSが保証するのは「暗号化」「認証」「完全性」の3つである。このうち暗号化と認証は、それぞれ別の暗号技術が担っている。本節では、その組み合わせ方と、そこに証明書がどう関わるかを整理する。
2.3.1. なぜ2種類の暗号を組み合わせるのか
暗号方式は大きく2種類あり、どちらも単独では通信の暗号化に使えない。
| 共通鍵暗号 | 公開鍵暗号 | |
|---|---|---|
| 鍵 | 暗号化と復号で同じ鍵を使う | 暗号化と復号で違う鍵を使う |
| 代表例 | AES、ChaCha20 | RSA、楕円曲線暗号 |
| 速度 | 速い | 遅い(数百〜数千倍) |
| 弱点 | 鍵をどうやって相手に渡すか(鍵配送問題) | 大量のデータの暗号化に向かない |
そこで、両者の長所だけを使う。
- 鍵の共有という一瞬の処理だけを公開鍵暗号で行う
- 通信本文という大量のデータは共通鍵暗号で暗号化する
この組み合わせをハイブリッド暗号方式と呼ぶ。TLSはこの方式を採用している。
用語解説(別記事)
2.3.2. 公開鍵暗号だけでは足りないもの
ハイブリッド暗号方式によって、盗聴は防げるようになったが、受け取った公開鍵が、本当に相手のものか分からない問題が残る。
クライアント ──▶ ??? (攻撃者) ──▶ サーバ(example.com)
↑ 自分の公開鍵をサーバのものだと偽って渡す
攻撃者が経路の途中で自分の公開鍵をすり替えれば、クライアントは攻撃者と暗号通信を確立してしまう。通信は正しく暗号化されているが、相手が違う。これを中間者攻撃(Man-in-the-Middle attack)と呼ぶ。
暗号化だけでは解決できない。「この公開鍵は確かにexample.comのものである」と、第三者が保証する仕組みが要る。それが公開鍵証明書である。
2.3.3. 公開鍵証明書とX.509
公開鍵証明書は、公開鍵と名前を結びつけ、第三者(CA)がその組に署名したものである。(RFC 5280 §3.1)
この「結びつけたデータ」をどういう形式で表すかを定めた標準規格が X.509 である。
- もとは ITU-Tの勧告として策定された、汎用の証明書フォーマット
- 適用範囲が広すぎるため、インターネットで相互運用するには絞り込みが必要だった
- そこでIETFが用途を限定した仕様を作った。それが RFC 5280
(RFC 5280 Abstract)
つまり、次のような関係になる。
- X.509 — 証明書の書式そのものの標準規格(ITU-T)
- RFC 5280 — X.509をインターネット用に絞り込んだ仕様(IETF)
- この記事で
opensslが作る証明書は、すべてこのX.509 v3形式である
2.3.4. TLS 1.3における役割分担
ここで注意が要る。「共通鍵を公開鍵で暗号化して相手に送る」という説明をよく見かけるが、TLS 1.3ではこの方式は使われない。(RFC 8446 §1.2)
TLS 1.3で残っている鍵交換は (EC)DHE(楕円曲線ディフィー・ヘルマン鍵共有)だけである。これは「共通鍵を暗号化して送る」のではなく、双方が公開値を交換し、それぞれが手元で同じ鍵を計算する方式である。鍵そのものは経路上を流れない。
結果として、TLS 1.3での役割は次のように分かれる。
| 目的 | 担う技術 | TLS 1.3での実体 |
|---|---|---|
| 通信本文の暗号化 | 共通鍵暗号 | AES-GCM、ChaCha20-Poly1305 |
| 共通鍵の共有 | 公開鍵暗号(鍵交換) | (EC)DHE |
| 相手の認証 | 公開鍵暗号(署名) | Certificate + CertificateVerify |
| 公開鍵と名前の結びつけ | 公開鍵証明書 | X.509 v3(RFC 5280) |
TLS 1.3において証明書は「鍵を渡すため」ではなく「相手を認証するため」だけに使われるのである。
※2.2.3で見たCertificateVerifyが署名を送っていたのは、このため。証明書に書かれた公開鍵は、暗号化ではなく署名の検証に使われる。
用語解説(別記事)
2.4. CA・証明書チェーン・信頼ストア
2.3において「公開鍵証明書は、CAが署名することで公開鍵と名前の結びつきを保証する」とのべたが、そのCAが本物であることは誰が保証するのかという問題がある。
本節では、この問いを出発点に、CA・証明書チェーン・信頼ストアの関係を整理する。
2.4.1. 信頼の無限後退
CAの証明書もまた、証明書である。ならば、その正しさを確かめるには署名した相手が要る。
サーバ証明書 ← 署名したのは CA-A
CA-A の証明書 ← 署名したのは CA-B
CA-B の証明書 ← 署名したのは CA-C
... 終わらない
このまま遡り続けても終わらない。どこかで「検証せずに信じる」と決めた地点がなければ検証は始まらない。
その地点をトラストアンカー(trust anchor / 信頼の起点)と呼ぶ。
2.4.2. 信頼ストア — 「検証」ではなく「事前配布」で止める
トラストアンカーになるのがルートCAの証明書である。
ルート証明書は自己署名されている。自分の秘密鍵で自分に署名しているので、署名そのものは何も証明していない。では何を根拠に信じるのか。それは、OSやブラウザにあらかじめ同梱されていることである。
この同梱された証明書の一覧を信頼ストア(トラストストア)と呼ぶ。
- macOSならキーチェーンアクセスの「システムルート」
- 信頼ストアに無いCAが署名した証明書は、検証に失敗する
つまり、PKI全体でただ一箇所、信頼ストアだけが「検証されない信頼」である。ここを起点にそれ以外のすべてが署名の検証によって導かれる。
RFC 5280のパス検証も、トラストアンカーを検証の対象ではなく入力として受け取る形になっている。(RFC 5280 §6.1.1 — パス検証への入力)
用語解説(別記事)
2.4.3. 証明書チェーン — 起点から末端までをつなぐ
トラストアンカーが決まっても、ルートCAが世界中の証明書を直接発行しているわけではない。間に 中間CA が入る。この連なりを証明書チェーン(certification path)と呼ぶ。(RFC 5280 §3.2)
発行は上から下へ、検証は下から上へ進む。検証する側は末端の証明書から出発し、署名した相手をたどって、信頼ストアに入っている証明書へ行き着けるかを確かめる。
用語解説(別記事)
2.4.4. 失効 — 期限を待たずに無効にする
証明書には有効期限があるが、何らかの理由により期限前に無効にしたいことがある。これを失効(revocation)と呼ぶ。
ただし、発行済みの証明書そのものを回収できない。証明書は端末の中にありこちらから消せない。そこで「これは無効である」という情報を別途配る対応をとる。(RFC 6960 Abstract)
| 方式 | 仕組み | 特徴 |
|---|---|---|
| CRL | 失効させた証明書のシリアル番号を並べたファイルをCAが定期的に発行する | まとめて配れる。反映が遅い |
| OCSP | 1枚ずつリアルタイムに問い合わせる | 新しい情報が得られる。応答サーバが要る |
この記事ではサーバ(nginx)側で検証するため、CRLファイルをnginxに置く形をとる。ssl_crlがそれにあたる。
用語解説(別記事)
2.4.5. プライベートCA
上記の構造を自作したCAが、プライベートCAである。
※より正確には、企業や組織が社内システムや特定の機器を安全に管理するため、独自に構築・運用する電子証明書のことを意味する。
- ルートCAを自分で作る(自己署名)
- 中間CAを自分で作る
- 端末の信頼ストアに、自分のルート証明書を手で登録する
対になるのがパブリックCA(公的CA) で、DigiCertやLet's Encryptのように、ルート証明書が各OSにあらかじめ同梱されている認証局を指す。
| パブリックCA | プライベートCA | |
|---|---|---|
| 信頼ストアへの掲載 | 同梱済み | 手動で追加が必要 |
| 誰でも検証できるか | できる | 追加した端末だけ |
| 発行できる名前 | ドメイン所有の確認が要る |
任意(*.internalなど実在しない名前も可) |
| 業界ルール(有効期間など) | 適用される | 適用されない |
| 用途 | 公開Webサイト | 社内システム、機器認証、検証環境 |
mTLSでプライベートCAを使う理由は明快である。
- クライアント証明書を自分たちで自由に発行したい
- 発行対象は自分たちが管理する端末なので、外部の誰かが検証する必要がない
- そもそもパブリックCAは、この用途のクライアント証明書を発行してくれない
この記事の5章以降でおこなうのは、この構造をすべて自分の手で組み立てる作業である。
2.5. その他の用語
用語解説(別記事)
次は3. 作成するCAの構成に進む。
全体の目次は「OpenSSLでプライベートCAを作る(全15章)」にある。