OpenSSLでx509証明書 (1) 〜 ルート認証局を作る 〜
OpenSSLを使って自己署名証明書の認証局(CA)を作ってみたのでメモ.
1. 自己署名証明書によるルート認証局を作る手順
1-1. 認証局のディレクトリ構造とファイルの配置
まず最初に証明書を作成する手順で必要なファイルの準備を行う ここでは認証局ディレクトリを「rootCA」とする.
以下の構造でディレクトリ/ファイルを配置.
rootCA/ ├── certs/ // <- 生成した証明書格納用ディレクトリ ├── conf/ // <- 設定ファイル配置ディレクトリ │ ├── signCA.cnf // /etc/ssl/openssl.cnf をコピー │ └── signCert.cnf // /etc/ssl/openssl.cnf をコピー ├── crl/ // 証明書失効リスト配置用 ├── crlnumber // 空ファイル. CAが使用する ├── index.txt // 空ファイル. CAが使用する. 証明書データベースファイル. ├── keys/ // 生成した秘密鍵を配置する ├── newcerts/ // 署名した証明書の控え ├── private/ // CAの秘密鍵を配置する ├── serial // テキストファイル. 00とだけ入力. 次の証明書のシリアル値. └── site/ // CAが使用する
#!/bin/sh # # "CA用のディレクトリを生成します.." # if [ $# -ne 1 ]; then echo "CAのディレクトリ構造を指定したDirectory以下に生成します." echo "[Usage] ./makeCAdirs.sh [Directoryパス]" exit 1 fi echo "CAのディレクトリ構造を生成しています" CADIR=$1 # rootCA echo "CADIR=${CADIR}" mkdir -p ${CADIR}/certs mkdir -p ${CADIR}/conf mkdir -p ${CADIR}/crl mkdir -p ${CADIR}/keys mkdir -p ${CADIR}/newcerts mkdir -p ${CADIR}/site mkdir -p ${CADIR}/private touch ${CADIR}/index.txt touch ${CADIR}/crlnumber echo 00 > ${CADIR}/serial echo "設定ファイルテンプレートを配置しています.." cp /etc/ssl/openssl.cnf ${CADIR}/conf/signCA.cnf cp /etc/ssl/openssl.cnf ${CADIR}/conf/signCert.cnf echo "完了!"
コレを実行.
$ ./makeCAdirs.sh rootCA
1-2. 設定ファイルの編集
認証局作成用、秘密鍵/証明書ペア作成用にそれぞれ設定ファイルを変更します.
ファイルの用途は以下の通り.
1-2-1. 認証局(CA)作成用設定ファイル(signCA.cnf)の編集
CAの秘密鍵生成と証明書作成に使用するsignCA.cnfを書き換える.
: [ CA_default ] # CAとして証明書署名要求へ署名するときに使用する設定 dir = /backup/sample/rootCA # ← 認証局のディレクトリ(絶対パス) certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/cacert.pem # CAの証明書 serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/cakey.pem # CAの秘密鍵 RANDFILE = $dir/private/.rand : : [ usr_cert ] # 中間認証局向けv3拡張設定です # 認証局=True basicConstraints=CA:TRUE # 証明書のタイプ. # SSL 認証局, メール認証局, コードの署名者 nsCertType = sslCA, emailCA, objCA # 証明書の用途 # 証明書の署名, CRL の署名者 keyUsage = cRLSign, keyCertSign # 証明書コメント. nsComment = "Sample Intermidiate CA Certificate" subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer : : [ v3_ca ] # 自己署名時に使用するv3拡張設定 # 認証局=True basicConstraints=CA:TRUE # 証明書のタイプ. # SSL 認証局, メール認証局, コードの署名者 nsCertType = sslCA, emailCA, objCA # 証明書の用途 # 証明書の署名, CRL の署名者 keyUsage = cRLSign, keyCertSign # 証明書コメント nsComment = "Sample Root CA Certificate" subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer :
1-2-2. 証明書作成用設定ファイル(signCert.cnf)の編集
実際に使用する証明書/秘密鍵を生成するための設定ファイル.(修正箇所のみ抜粋)
後ほどこのファイルを使って証明書署名要求(CSR)の作成と証明書への署名を行う.
2017年5月の Chrome version 58 以降、サーバ証明書のCommonNameが無視されてsubjectAltName(SAN)が参照されるようになり、subjectAltName(SAN)が指定されていないとhttpsサーバで証明書エラーとなり暗号化されないらしい.
https用のサーバ証明書としては、マルチドメイン証明書対応が必須.
ここではマルチドメインに対応した証明書を作成できるように設定する
: [ CA_default ] # CAとして証明書署名要求へ署名するときに使用する設定 dir = /backup/sample/rootCA # ← 認証局のディレクトリ(絶対パス) certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/cacert.pem # CAの証明書 serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/cakey.pem # CAの秘密鍵 RANDFILE = $dir/private/.rand : : [ usr_cert ] # CAではない basicConstraints=CA:FALSE # 証明書タイプ指定 # SSLサーバ証明書, SSLクライアント証明書, コード署名用証明書, S/MIME証明書 nsCertType = server, client, objsign, email # 証明書の用途 # 否認防止, 署名, キーの暗号化 keyUsage = nonRepudiation, digitalSignature, keyEncipherment # 証明書のコメント nsComment = "Sample Certificate with Sample CA" # CN代替名の挿入 subjectAltName = @dummy_names subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # CNの代替名リストのダミーです # ** 使用時にコマンドで置換します ** [dummy_names] # DNS.1, DNS.2, ... と入力していきます. # DNSはFDQN, IPはIPアドレスを入力します DNS.1=localhost #DNS.2=p1234.hogehoge.co.jp #DNS.3=localhost #IP.1=192.168.11.128 : :
1-3. ルート認証局(CA)の秘密鍵と自己署名証明書の生成
以下のコマンドを実行
鍵ビット長はセキュリティ上、RSA 2048bit を指定するのが推奨されているらしい.
$ openssl req -new -newkey rsa:[鍵ビット長] \ -x509 -sha256 -days [有効日数]\ -config {rootCAのDir}/conf/signCA.cnf \ -keyout {rootCAのDir}/private/cakey.pem \ -out {rootCAのDir}/cacert.pem
- 以下の順で入力を求められるので対応.
- (1)秘密鍵のパスワードを尋ねられるので入力.
※ このパスワードは証明書署名要求(CSR)への署名時に必要になる. - (2)証明書のSubject情報(C/ST/O/OU/CN/E)を尋ねられるので適当に入力.
コマンド実行後は以下のディレクトリ構成になる.
rootCA/ ├── cacert.pem // <-- 生成したrootCAの自己署名証明書 ├── certs/ ├── conf/ │ ├── signCA.cnf │ └── signCert.cnf ├── crl/ ├── crlnumber ├── index.txt ├── keys/ ├── newcerts/ ├── private/ │ └── cakey.pem // <-- 生成したrootCAの秘密鍵 ├── serial └── site/
ルート認証局は以上で完成。