オレオレ (サーバ/クライアント) 証明書の発行
[最終更新] (2019/06/01 01:22:17)
最近の投稿
注目の記事

概要

証明書は認証局 (CA) が公開鍵 (をもとに情報を付加した証明書署名要求 (CSR; certificate signing request)) に署名をしたものです。一般的に証明書は公開鍵を内包しています。

上記ページで概念的に紹介した、サーバ証明書およびクライアント証明書を実際にコマンド例を示しつつ発行します。

認証局 (CA) を構築

証明書は認証局 (CA) が 証明書署名要求 (CSR; certificate signing request) に署名をしたものです。認証局 (CA) は秘密鍵を持っています。署名にはその秘密鍵を使用します。つまり、署名に必要なものは秘密鍵だけです。認証局の秘密鍵以外の適当な秘密鍵で署名すると形式的には証明書が完成します。しかしながらその適当な秘密鍵の保持者は証明書の信頼性を第三者に一般に保証することができないためオレオレ証明書などと称されます。

  • 認証局の秘密鍵を使用する場合
    • サーバ証明書の運用が可能
    • クライアント証明書の運用が可能
  • 認証局のものでない単なる秘密鍵を使用する場合
    • サーバ証明書の運用が可能 (オレオレ証明書)
    • クライアント証明書の運用が不可能

認証局は自分で構築することができます。これを俗にオレオレ認証局と称します。

  • 認証局の秘密鍵を使用する場合
    • サーバ証明書の運用が可能
    • クライアント証明書の運用が可能
  • オレオレ認証局の秘密鍵を使用する場合
    • サーバ証明書の運用が可能 (これもオレオレ証明書です。オレオレサーバ証明書)
    • クライアント証明書の運用が可能 (オレオレクライアント証明書)

クライアント証明書の運用を考える場合は必ず認証局が必要です。ここではベリサインなどの認証局は使用せず、独自にオレオレ認証局を構築します。オレオレクライアント証明書の運用を考えているということになります。オレオレサーバ証明書の運用のみを考える場合は以降の手順は不要です。

構築コマンド例

root で作業します。なお、作業環境は CentOS 6.6 です。

$ sudo su -l

PKI ディレクトリに移動します。

$ cd /etc/pki/

独自認証局を構築するためのディレクトリが用意されています。中身は空です。

$ ls /etc/pki/CA/
certs  crl  newcerts  private

必要なファイルをコピーしてきます。

$ cp tls/misc/CA CA/
$ cp tls/openssl.cnf CA/

内容を編集します。

  • CA
    • $SSLEAY_CONFIG が最初に登場する前に一行 SSLEAY_CONFIG="-config /etc/pki/CA/openssl.cnf" 追加
    • DAYS および CADAYS の既定値をそれぞれ 100 年 (36500 日) に変更して事実上無期限にする
    • REQREQ="$OPENSSL req $SSLEAY_CONFIG -sha256" に変更 (sha256 を既定値にする)
    • CACA="$OPENSSL ca $SSLEAY_CONFIG -md sha256" に変更 (sha256 を既定値にする)
  • openssl.cnf
    • req_distinguished_name セクションの既定値を変更 countryName_default, stateOrProvinceName_default, localityName_default, 0.organizationName_default
    • default_days を 100 年 (36500 日) に変更して事実上無期限にする

認証局用の秘密鍵を生成して、更にその秘密鍵をもとに作成した公開鍵と国情報などを合わせた CSR を生成します。更に自分の秘密鍵で署名します。/etc/pki/CA/CA には CATOP=/etc/pki/CA という一行があります。ルート CA は自分で自分の CSR に署名します。これらの処理はコマンド一つで実行できるようになっています。

$ cd /etc/pki/CA
$ ./CA -newca (最初はそのままエンターです)

作成中に求められるコモンネームは認証局の識別子です。ここでは "MyCA" としました。また、認証局の秘密鍵のパスワードは my_ca_pass としました。認証局用の CSR を生成するときに認証局秘密鍵のパスワードが早速必要になります。

成果物

  • private/cakey.pem (認証局秘密鍵)
  • cacert.pem (自分の秘密鍵で署名した認証局証明書)
  • newcerts/DB04B363DA63FFA3.pem (内容は cacert.pem と同じ。newcerts/ には今後新規発行した証明書が格納されていきます。証明書ディレクトリ。内容は index.txt で管理されます)
  • careq.pem (cacert.pem の発行に使用した CSR)

証明書破棄リスト (CRL)

将来的に証明書を無効にする場合に備えて破棄リストを生成しておきます。

$ cd /etc/pki/CA
$ echo 00 > crlnumber
$ openssl ca -config openssl.cnf -gencrl -out crl.pem

成果物

  • crl.pem (証明書破棄リスト)
  • crlnumber (内容がインクリメントされて "01" になった)

以上で CA が構築されました。

サーバ証明書の発行

CA を構築していない場合

こちらのページなどを参考にします。一般的にオレオレ証明書の作成といった場合は CA を構築せずに以下のようなコマンドで発行する場合が多いようです。

秘密鍵の作成

$ openssl genrsa -out my-private-key.pem 2048

CSR の作成 (コモンネームなどの情報を入力)

$ openssl req -sha256 -new -key my-private-key.pem -out csr.pem

認証局 CA がないため自分の秘密鍵を流用して署名 (100 年の有効期間)

$ openssl x509 -sha256 -req -days 36500 -in csr.pem -signkey my-private-key.pem -out my-certificate.crt

成果物

  • my-certificate.crt (オレオレサーバ証明書)
  • my-private-key.pem (サーバに設置する秘密鍵。パスフレーズなし)

それぞれ以下のコマンドで情報確認が可能

秘密鍵

$ openssl rsa -text -in my-private-key.pem
Private-Key: (2048 bit)
...

CSR

$ openssl req -text -in csr.pem

証明書

$ openssl x509 -text -in my-certificate.crt

CA を構築した場合

「CA を構築していない場合」の手順または以下のバッチコマンドで秘密鍵と CSR を準備します。

$ sudo su -l
$ cd /etc/pki/CA
$ ./CA -newreq

パスフレーズは my_server_pass としました。CN は localhost としました。成果物は newreq.pem および newkey.pem です。次に構築した CA で署名します。

$ sudo su -l
$ cd /etc/pki/CA
$ ./CA -sign

成果物 newcert.pem が生成されました。同じ内容のファイルが newcerts/DB04B363DA63FFA4.pem (ファイル名はシリアル番号で環境依存) にも生成されています。シリアル連番 serial や発行証明書のリスト index.txt も更新されました。カレントディレクトリに生成されたままのファイルを移動させて整理します。newcerts のシリアル番号とファイル名を同じにしておきます。

$ mkdir csr
$ mv newreq.pem csr/DB04B363DA63FFA4.pem
$ mv newkey.pem private/DB04B363DA63FFA4.pem

内容としては同じではありますが、使い勝手をよくするために秘密鍵からパスワードを解除して証明書からは余分な文字列を除去して依頼主に渡します。

$ cd /etc/pki/CA
$ mkdir share

$ openssl rsa -in private/DB04B363DA63FFA4.pem -out share/localhost.key

$ mv newcert.pem share/localhost.crt
$ openssl x509 -in share/localhost.crt -out share/localhost.crt

証明書から削除した余分な文字列は上述の通りコマンドで再確認できます。

$ openssl x509 -text -in share/localhost.crt

サーバ証明書の使用

Apache の設定例

必要なソフトウェアをインストールします。

$ sudo yum install httpd mod_ssl

用意したサーバ証明書を設定します。

$ sudo vi /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/pki/CA/share/localhost.crt
SSLCertificateKeyFile /etc/pki/CA/share/localhost.key

サービスを起動します。

$ sudo service httpd start

アクセスしてみましょう。

$ curl https://localhost/  ←オレオレサーバ証明書のためエラー
$ curl https://localhost/ -k  ←証明書を強制的に信頼するオプション
$ curl https://localhost/ --cacert /etc/pki/CA/cacert.pem  ←指定した認証局証明書を信頼するオプション

上記 curl コマンドの二つ目はブラウザで信頼性のないサーバ証明書を個別に信頼する処理に相当します。三つめは構築した CA の証明書をブラウザにインポートすることに相当します。Firefox の場合は以下のようになります。

Firefox → オプション → 詳細 → 証明書 → 証明書を表示 → 認証局証明書 → インポート → cacert.pem → すべてチェックして OK

証明書をインポートした CA で署名された証明書であればブラウザは信頼のある証明書として扱うようになります。ただし、コモンネーム (CN) が一致しない場合はやはりブラウザに信頼されないことに注意してください。他人のサイトの証明書を勝手に利用したなりすまし防止のためです。

nginx の設定例

必要なソフトウェアをインストールします。

$ sudo yum install epel-release (環境によっては不要)
$ sudo yum install nginx

用意したサーバ証明書を設定します。コメントアウトをすべて解除して以下のように編集します。

$ sudo vi /etc/nginx/conf.d/ssl.conf
ssl_certificate /etc/pki/CA/share/localhost.crt;
ssl_certificate_key /etc/pki/CA/share/localhost.key;

サービスを起動します。

$ sudo service nginx start

アクセスしてみましょう。

$ curl https://localhost/  ←オレオレサーバ証明書のためエラー
$ curl https://localhost/ -k  ←証明書を強制的に信頼するオプション
$ curl https://localhost/ --cacert /etc/pki/CA/cacert.pem  ←指定した認証局証明書を信頼するオプション

AWS ELB の設定例

Apache や nginx は HTTP で動作させて ELB にサーバ証明書をアップロードすることができます。クライアントは HTTPS 通信を ELB に対して行います。詳細は『SSL 通信に対応した ELB』に記載しました。

クライアント証明書の発行

この続きが気になる方は

オレオレ (サーバ/クライアント) 証明書の発行

残り文字数は全体の約 46 %
tybot
100 円
関連ページ
    概要 ロボットシミュレータ Gazebo を ROS 開発で利用するための簡単な手順を記載します。ここでは Debian9 を利用します。個別にインストールすることもできますが、ROS を ros-melodic-desktop-full でインストールすれば gazebo もインストールされます。 URDF モデルの作成
    概要 SSH 認証においても HTTP サーバ等で利用するオレオレ (サーバ/クライアント) 証明書と同様に CA を利用できます。本ページでは CA は独自に構築します。 authorized_keys を用いないクライアント認証 SSH サーバ側の authorized_keys ファイルを更新する必要がないため管理も簡易化されます。共通の秘密鍵を複数人で使い回す必要もなくなります。
    概要 JDK でインストールされる keytool コマンドの利用方法を、『オレオレ (サーバ/クライアント) 証明書の発行』で利用する openssl コマンドと対比してまとめます。keytool コマンドは、こちらのページで hello world チュートリアルを記載した Android Studio のドキュメント
    概要 ファイルやメールの暗号化を行うための PGP (Pretty Good Privacy) の別実装である GNU Privacy Guard (GnuPG, GPG) について基本的なコマンドを記載します。通信の暗号化を行う SSL/TLS と区別します。例えば Thunderbird では GnuPG を利用するための Enigmail というアドオンが存在します。2020 年の夏には、
    概要 『グローバルIP を持たない GCP VM への SSH 接続方法』で記載した IAP tunnel は、HTTPS トンネル内で TCP パケットを forward するための技術です。 この HTTPS トンネルは、ユーザと tunnel.cloudproxy.app の間で確立される WebSocket です。
    概要 Snowflake はクラウド上に構築されたデータプラットフォームです。基本的な使い方を記載します。 Snowflake Architecture Snowflake Architecture Hadoop 等の big data プラットフォームは利用していません。 顧客管理ではなく、Snowflake 社が管理する AWS, GCP, Azure で稼働します。