クライアント証明書の発行と失効を運用に載せる

 公開 2026-10-05

Viewer mTLS を採用したあとに残るのは、秘密鍵をどこで生成し、発行・配布・更新・失効を誰がどう回すかである。鍵の生成場所の選択、3つの操作が別物であること、端末への取り込みで詰まる点を整理する。

CloudFront の Viewer mTLS を採用すると決めたあと、残る論点は技術の選定ではない。 秘密鍵をどこで生成し、誰が署名し、配った証明書をどう失効させるかである。 ここを決めないまま始めると、秘密鍵が人の手を渡り歩き、有効期限で黙って止まり、使われていない証明書が台帳に残る。

本稿では、鍵の生成場所の選び方、発行・更新・失効が別の操作であること、 端末への取り込みで実際に詰まる点を整理する。 方式の比較とこの手段を選ぶかどうかは親記事にある。

1. 誰が何を持つか

名前が似ているため、どれを秘密として扱うのかが混ざりやすい。先に分けておく。

もの
置き場所
秘密か
役割
CA の秘密鍵
署名する仕組みの中だけ
秘密(最も強い)
これで署名したものが証明書になる
利用者の秘密鍵
端末
秘密
接続時に、証明書の持ち主であることを示す
CSR
利用者が作成して送る
公開してよい
公開鍵と Subject が入る。秘密鍵は含まれない
証明書
端末と台帳
公開してよい
接続時に相手へ提示する
PKCS#12
利用者が受け取る
秘密
秘密鍵を含むため、パスフレーズを付けて渡す

CA の秘密鍵を扱える範囲が、この仕組みで最も強い権限になる。 その鍵で署名すれば、任意の Subject の証明書を作れる。 発行の操作を画面に出すかどうかは、この鍵に触れる範囲を広げないことと引き換えに決める。

2. 秘密鍵をどこで生成するか

方式
秘密鍵が通る経路
利用者の手間
向く場面
サーバーで生成
サーバーで生成し、PKCS#12 にまとめて配る
少ない。受け取って取り込むだけ
利用者が不特定多数で、手順を踏ませられない
ブラウザで生成
端末内で生成し、CSR だけを送る
中。画面の案内に沿って進む
利用者が多く、端末に道具を入れさせられない
端末で生成
端末から出ない。CSR だけを送る
多い。コマンドの操作が要る
利用者が限られ、手順を渡せる

ブラウザ内で鍵を生成する keygen 要素は、現在の HTML 規格では使ってはならない機能として扱われている。 証明書の登録用途には Web Cryptography API で鍵の組を生成し、利用者が手で取り込む形が案内されている。 ブラウザ方式を採るなら、その画面を自分で実装することになる。

サーバーで生成する方式は、サーバーが一度は秘密鍵を保持する。 PKCS#12 をその場でダウンロードさせる仕組みはこの方式である。 生成後に保存しない運用にはできるが、「保持していない」ことを設計で示すのは難しい。

3. CSR を受け取る構成

端末で秘密鍵を生成し、CSRを作成し、CAの鍵で署名し、台帳に登録し、配布して端末へ取り込むまでの流れ。各段に注記が付き、秘密鍵は端末から出さない、CSRに秘密鍵は含まれない、CAの鍵に触れる範囲は広げない、端末へ取り込んだ時点で初めてその端末から接続できることを示す図
秘密鍵は端末から出ず、CSR と証明書だけが行き来する

対象が社内の運用担当という限られた相手のため、端末で鍵を生成する方式を採った。 秘密鍵は端末から出ず、画面と台帳を通るのは CSR と証明書だけになる。

決めたこと
理由
秘密鍵を受け取らない
受け取らなければ漏らす経路がない。台帳にも残らない
CSR の作り方を画面に書く
手間が増える方式のため、手順を画面の中に置く。別の文書を探させない
Subject は画面が組み立てる
Subject は接続元の識別子として記録に残り、照合にも使う。自由入力にしない

4. 発行・更新・失効は別の操作である

運用でつまずくのは、次の3つが別物だからである。画面の作りでも、ここを分けて見せる。

区別
内容
画面で示すこと
発行と配布は別
発行しても、配って取り込ませるまで、その端末からは接続できない
未配布の証明書に印を付ける
更新では旧証明書は失効しない
更新は新しい1枚を発行するだけ。旧証明書は有効期限まで通る
有効なまま残る旧証明書を端末の行に出し、そこから失効させられるようにする
失効の受付と反映は別
失効が接続側の照合へ反映されるまでに間がある
「受け付けた」と「反映した」を同じ表示にしない

有効期限も、台帳の状態とは別に扱う。 失効させていなくても期限を過ぎた証明書は通らないため、状態の値ではなく notAfter から導く。

失効を効かせる仕組みは、別に用意する必要がある。 CloudFront は Trust Store に対して証明書を検証するが、失効したかどうかの確認は組み込みではない。 失効させた通し番号を保持し、接続時に動く関数が照合する構成が案内されている。 つまり「失効させる」という操作には、台帳への記録だけでなく照合先への反映までが含まれる。

5. 端末への取り込み

秘密鍵と証明書をまとめた PKCS#12 を作れるのは、秘密鍵を持っている側だけである。 秘密鍵を受け取らない構成では、画面でこのファイルを作れない。利用者が自分の端末で作る。

まとめるときの暗号方式には注意が要る。 新しい版の OpenSSL が既定で使う方式(PBES2 / AES-256-CBC、MAC は SHA-256)でまとめたファイルは、 macOS のキーチェーンが取り込めなかった(2026-10 に確認)。古い方式を明示するとそのまま取り込めた。

取り込みの手順は画面に書いておく。 証明書の配布は年に数回しか起きないため、手順は必ず忘れられる。

6. 証明書は端末までしか示さない

接続してきた証明書の情報(通し番号、発行者、Subject、有効期間)は、ヘッダーとしてオリジンへ渡せる。 ただしオリジンリクエストポリシーに明示的に挙げる必要があり、他の目的で必要なヘッダーと設定が両立しないことがある。 アプリケーションが接続元の証明書を参照する構成にするかは、この手当てを含めて決める。

渡したとしても、証明書が示すのは端末までである。 誰であるかは利用者の認証が決める。 親記事の軸でいえば、クライアント証明書は到達範囲だけを受け持ち、本人性は別に決める。

本人性を前段に置かない構成も採れる。 その場合、前段は端末だけを確かめ、誰が操作しているかはアプリケーション側で確かめることになる。 証明書だけで接続してきた相手に対して、画面は返るがデータは返らない、という状態もこの形である。

7. 増える運用

観点
見る理由
有効期限
黙って切れる。切れた端末からは接続できなくなる
失効漏れ
更新のあとに旧証明書が有効なまま残る
未配布
発行しただけのものは誰の手にもない。残り続けるなら、その発行は不要だった
拒否された接続
TLS ハンドシェイクで切れた接続はアプリケーションのログに出ない

端末ごとの台帳と、これらの出し方は操作できる画面に置いた。

アクセス制限の切り替え(運用画面例。AWSに接続しないモック)

8. まとめ

設計判断
内容
秘密鍵を受け取らない
端末で生成し、CSR と証明書だけを行き来させる。相手が限られるから選べる方式である
Subject は画面が決める
識別子として記録と照合に使うため、利用者に自由入力させない
3つの操作を分けて見せる
発行と配布、更新と失効、失効の受付と反映。同じ表示にしない
失効には反映まで含める
失効の確認は組み込みではない。照合先への反映までを操作とする
証明書と認証を別の層にする
証明書は端末まで、認証は個人まで

クライアント証明書は認証を強くする道具ではなく、接続元の端末を限定する道具である。 限定した結果として増える運用(有効期限・配布・失効)を引き受ける場所を決めてから採用する。

関連する記事