暗号技術における基本的な公開鍵基盤 PKI

LinuxBeginner
オンラインで実践に進む

はじめに

この実験(Lab)では、HTTPS を含むインターネット上のセキュリティの多くを支える基盤である公開鍵基盤(PKI: Public Key Infrastructure)の基礎を探求します。PKI は、デジタル証明書を作成、管理、配布、使用、保存、失効させ、公開鍵暗号を管理するために必要な役割、ポリシー、ハードウェア、ソフトウェア、および手順のセットです。

openssl コマンドラインツールを使用して、PKI の主要な機能を実行する実践的な経験を積みます。あなたは自身の認証局(CA: Certificate Authority)として振る舞い、Web サーバー用の証明書を発行し、証明書の信頼チェーンを検証し、最終的にその証明書を失効させます。すべての操作は ~/project ディレクトリ内で行われます。

PKI の基礎の理解

このステップでは、PKI の基本的な概念について説明します。このステップで実行するコマンドはありません。目的は、実践的な演習を開始する前に、強固な理論的基盤を築くことです。

公開鍵基盤(PKI: Public Key Infrastructure)

PKI は、電子通信のセキュリティを強化するために設計されたフレームワークです。これは、認証局(CA: Certificate Authority) を介して、公開鍵をそれぞれのユーザーID にバインドするために公開鍵暗号を使用します。このバインドは、登録および発行プロセスを通じて確立されます。

認証局(CA: Certificate Authority)

認証局は、デジタル証明書を発行する信頼されたエンティティです。CA は、証明書の主体(所有者)と、その証明書に依存する当事者の両方から信頼される第三者として機能します。CA の主な役割は、特定のユーザーにバインドされた公開鍵にデジタル署名を行い、公開することです。

デジタル証明書

デジタル証明書は電子文書であり(多くの場合 X.509 標準に従います)、以下を含みます。

  • 所有者の公開鍵。
  • 所有者の識別情報(名前やホスト名など)。
  • 発行者(CA)の情報とデジタル署名。
  • 有効期間(開始日と終了日)。
  • 一意のシリアル番号。

証明書に対する CA の署名は、証明書に含まれる公開鍵が、証明書に記載されているエンティティに属することを証明します。

信頼チェーン(Trust Chain)

信頼チェーン(または証明書チェーン)は、エンドエンティティ証明書(例:example.com のもの)から始まり、ルート CA 証明書で終わる一連の証明書です。

  1. ルート CA 証明書: これは、究極の権限であるルート CA による自己署名証明書です。これらの証明書は、ブラウザまたはオペレーティングシステムの「トラストストア」にあらかじめインストールされています。
  2. 中間 CA 証明書: 大規模な CA は、ルート鍵を保護するために、中間 CA を使用してエンドユーザーに証明書を発行することがよくあります。中間証明書はルート CA によって署名されます。
  3. エンドエンティティ証明書: これは、特定のサーバーまたはユーザーに発行される証明書です。中間 CA(またはより単純な設定ではルート CA)によって直接署名されます。

ブラウザがサーバーの証明書を受け取ると、発行者の証明書を確認することで署名を検証します。ブラウザは、トラストストアにすでに存在するルート CA に到達するまで、このチェーンをたどります。チェーンが有効であり、すべての署名が一致する場合、そのサーバーは信頼できると見なされます。

次のステップでは、独自のルート CA を作成します。

認証局 (CA) の作成

このステップでは、認証局(CA)として振る舞い、その基盤となるコンポーネント、すなわち秘密鍵と自己署名ルート証明書を作成します。すべてのコマンドはターミナルで実行され、すべてのファイルは現在のディレクトリ ~/project 内に作成されます。

まず、CA の秘密鍵を生成します。この鍵は PKI の最も重要な秘密情報であり、CA によって発行されるすべての証明書に署名するために使用されます。

openssl genpkey -algorithm RSA -out ca.key

次に、自己署名ルート証明書を作成します。ルート証明書は、それが信頼の究極のアンカーであるため、自己署名されます。署名するための上位の権限は存在しないからです。

証明書を生成するために次のコマンドを実行します。証明書の内容を対話的ではない方法で提供するために、-subj 引数を使用します。

openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.pem -subj "/C=US/ST=California/L=MountainView/O=MyLab/CN=MyLabRootCA"

このコマンドの内訳を見てみましょう。

  • req: 証明書署名要求(CSR)および証明書生成ユーティリティ。
  • -x509: CSR の代わりに自己署名証明書を出力します。
  • -new: 新しい証明書を作成します。
  • -nodes: 「No DES」の略で、秘密鍵がパスフレーズで暗号化されないことを意味します。これは、この実験での簡略化のためです。
  • -key ca.key: 署名に使用する秘密鍵を指定します。
  • -sha256: 署名に SHA-256 ハッシュアルゴリズムを使用します。
  • -days 365: 証明書の有効期間を 365 日に設定します。
  • -out ca.pem: 新しい証明書の出力ファイルを指定します。
  • -subj "/C=.../CN=...": 主体の詳細情報を提供します。CN(Common Name)は主要な ID であり、CA の場合はその名前になります。

これで、CA の秘密鍵(ca.key)とルート証明書(ca.pem)ができました。新しい CA 証明書の内容を確認できます。

openssl x509 -in ca.pem -text -noout

出力全体をスクロールし、Issuer(発行者)フィールドと Subject(主体)フィールドが同一であることを確認してください。これにより、自己署名されていることが確認できます。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
        Validity
            Not Before: ...
            Not After : ...
        Subject: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
        Subject Public Key Info:
            ...

サーバー証明書の発行

このステップでは、サーバー所有者をシミュレートし、証明書を要求します。サーバー用の秘密鍵と証明書署名要求(CSR)を生成し、その後、前のステップで作成した CA を使用して CSR に署名し、有効な証明書を発行します。

まず、サーバー用の秘密鍵を生成します。この鍵はサーバー自体で秘密に保つ必要があります。

openssl genpkey -algorithm RSA -out server.key

次に、証明書署名要求(CSR)を作成します。CSR は、公開鍵や、組織名やドメイン名など証明書に含まれるその他の情報を含むエンコードされたテキストのブロックです。CSR は署名のために CA に送信されます。

openssl req -new -key server.key -out server.csr -subj "/C=US/ST=California/L=MountainView/O=MyWebServer/CN=example.com"

サーバー証明書の場合、CN(Common Name)はサーバーのドメイン名(この場合はexample.com)と一致する必要があることに注意してください。

次に、CA として振る舞い、サーバーの CSR(server.csr)に CA の秘密鍵(ca.key)を使用して署名します。この操作により、最終的なサーバー証明書(server.crt)が作成されます。

openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.crt -days 300 -sha256

新しいオプションを確認しましょう。

  • x509 -req: これは OpenSSL に CSR を処理するように指示します。
  • -in server.csr: 入力 CSR ファイル。
  • -CA ca.pem: 発行者として使用する CA の証明書。
  • -CAkey ca.key: 署名に使用する CA の秘密鍵。
  • -CAcreateserial: これにより、シリアル番号ファイル(ca.srl)が作成および管理されます。これは、CA によって発行されるすべての証明書が一意のシリアル番号を持つことを保証するために必要です。
  • -days 300: サーバー証明書の有効期間。これは CA 証明書の有効期間よりも短く設定する必要があります。

最後に、新しく作成されたサーバー証明書を確認します。

openssl x509 -in server.crt -text -noout

出力において、Issuer(発行者)フィールドと Subject(主体)フィールドを観察してください。Issuer はあなたの CA(MyLabRootCA)であり、Subject はあなたのサーバー(example.com)であるはずです。これにより、証明書があなたの CA によって正しく発行されたことが確認できます。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: ...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
        Validity
            Not Before: ...
            Not After : ...
        Subject: C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
        ...
    Signature Algorithm: sha256WithRSAEncryption
         ...

証明書チェーンの検証

このステップでは、証明書チェーンを検証する方法を学びます。これは、ウェブブラウザのようなクライアントがサーバーの証明書が信頼できるかどうかを判断するために実行するプロセスです。クライアントは、証明書が信頼できる CA によって署名されているかを確認します。

このチェックを実行するために、openssl verify コマンドを使用できます。ルート証明書を提供することにより、OpenSSL にどの CA を信頼するかを伝える必要があります。

ca.pem ルート証明書に対して server.crt を検証するために、次のコマンドを実行します。

openssl verify -CAfile ca.pem server.crt

出力は次のようになるはずです。

server.crt: OK

この OK ステータスは、次のことを確認します。

  1. server.crt 証明書が、ca.pem 内の公開鍵に対応する秘密鍵によって実際に署名されたこと。
  2. 証明書が失効していないこと。

次に、検証側が信頼できる CA のリストに私たちの CA を持っていない場合に何が起こるかを見てみましょう。これは、-CAfile オプションなしで verify コマンドを実行することでシミュレートできます。

openssl verify server.crt

今回は、コマンドは次のようなエラーで失敗します。

C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.crt: verification failed

「unable to get local issuer certificate」(ローカル発行者証明書を取得できません)というエラーは、システムがデフォルトのトラストストア内で発行者(MyLabRootCA)の証明書を見つけられなかったことを意味します。これは、信頼の連鎖を確立するために、クライアントがルート CA 証明書を持っていることが不可欠である理由を示しています。

証明書失効のシミュレーション

このステップでは、証明書を失効させる方法を学びます。失効は、証明書の秘密鍵が侵害された場合や、証明書が自然な有効期限前に不要になった場合に不可欠なプロセスです。これは証明書失効リスト(CRL)を使用して管理されます。

CRL は、CA によって発行され、失効させたすべての証明書のシリアル番号を含む、デジタル署名されたリストです。クライアントは CRL をダウンロードして、受け取った証明書がまだ有効であるかを確認できます。

失効を管理するために、openssl は CA のデータベースファイル(index.txt および serial)をどこで見つけるかを知るために、小さな設定ファイルが必要です。この実験(Lab)のセットアップスクリプトは、必要なディレクトリ(my-ca)とファイルはすでに作成しています。次に、設定ファイルを作成します。

cat コマンドを使用して my-ca.conf を作成します。

cat << EOF > my-ca.conf
[ ca ]
default_ca = CA_default

[ CA_default ]
dir = ./my-ca
database = \$dir/index.txt
serial = \$dir/serial
private_key = ca.key
certificate = ca.pem
default_md = sha256
policy = policy_anything
crl_extensions = crl_ext
default_crl_days = 30

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ crl_ext ]
authorityKeyIdentifier=keyid:always
EOF

この設定ファイルは、OpenSSL が認証局(CA)として動作する方法を指示します。各セクションの機能は次のとおりです。

  • default_ca = CA_default: メインの CA 設定セクションを指します。
  • dir = ./my-ca: データベースファイル用の CA 作業ディレクトリ
  • database = $dir/index.txt: 証明書データベース(発行済み/失効済み証明書を追跡)
  • serial = $dir/serial: 一意の証明書 ID 用のシリアル番号ファイル
  • private_key = ca.key: 証明書署名に使用する CA の秘密鍵
  • certificate = ca.pem: CA 自身の証明書ファイル
  • default_md = sha256: 署名用のハッシュアルゴリズム(SHA-256)
  • policy = policy_anything: 証明書の検証ルール
  • crl_extensions = crl_ext: CRL の書式設定オプション
  • default_crl_days = 30: CRL の有効期間(30 日間)
  • countryName = optional: 国コード
  • stateOrProvinceName = optional: 都道府県
  • localityName = optional: 市区町村/場所
  • organizationName = optional: 組織名
  • organizationalUnitName = optional: 部門
  • commonName = supplied: ドメイン/サーバー名(必須)
  • emailAddress = optional: E メールアドレス
  • authorityKeyIdentifier=keyid:always: CRL に CA 識別子を含めて検証を容易にします

この設定ファイルは、CA の「運用マニュアル」です。OpenSSL に鍵の場所、証明書の保存方法、および証明書の発行と失効に従うべきルールを伝えます。

次に、サーバー証明書(server.crt)を失効させます。このコマンドは証明書のシリアル番号を検索し、index.txt データベースファイル内で失効済みとしてマークします。

openssl ca -config my-ca.conf -revoke server.crt

失効を確認する出力が表示されます。

失効後、更新された CRL を生成して公開する必要があります。

openssl ca -config my-ca.conf -gencrl -out my-ca.crl

これにより、失効した証明書のリストを含むファイル my-ca.crl が作成されます。

最後に、サーバー証明書を再度検証してみますが、今回は CRL も提供します。適切な検証プロセスでは、失効を確認する必要があります。

openssl verify -CAfile ca.pem -CRLfile my-ca.crl -crl_check server.crt

コマンドは、明確なメッセージとともに失敗します。

C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 23 at 0 depth lookup: certificate revoked
error server.crt: verification failed

「certificate revoked」(証明書は失効しました)というエラーは、私たちの失効プロセスが成功したことを確認します。クライアントは、CRL をチェックする際に、example.com の証明書がもはや信頼できないことを正しく識別しました。

まとめ

おめでとうございます!この公開鍵基盤(PKI)の基礎に関する実験(Lab)を無事に完了しました。デジタル通信を保護するための基本的な操作について実践的な経験を積むことができました。

この実験(Lab)では、以下のことを学びました。

  • PKI、認証局(CA)、および信頼チェーンのコアコンセプトを理解する。
  • 秘密鍵を生成し、自己署名証明書を作成することで、独自のシンプルなルート CA を作成する。
  • CA の鍵で証明書署名要求(CSR)に署名することにより、サーバー証明書を発行する。
  • openssl verify コマンドを使用して証明書の信頼チェーンを検証する。
  • 証明書失効リスト(CRL)を生成・使用することにより、証明書を失効させ、その失効ステータスを確認する。

これらのスキルは、セキュアなシステムを管理し、インターネット上で信頼がどのように確立されるかを理解するための基礎となります。