OpenSSLでプライベート認証局の構築(ルートCA、中間CA)


はじめに

このエントリはOpenSSLを利用したPKIを構築する手順について記載します。
PKIそのものや技術背景などの記載はありません。

概要

以下のようにルートCAと中間CAを作成します。

更新履歴

2020.1.28 図の追加と引数を一部変更(example.netにしたりとか)
      と、おまけの、一発構築コピペテキストも修正しました。

対象機器および環境

  • CentOS7(7.6.1810)

このエントリを読むとできること

  • LinuxのOpenSSLを利用して
  • ルートCAと中間CAを作成して
  • 証明書発行できる環境が準備できる

はず。

事前準備

ディレクトリ配置

mkdir -p /opt/pki
mkdir /opt/pki/configs
mkdir /opt/pki/crl
mkdir /opt/pki/RootCA
mkdir /opt/pki/InterCA
mkdir /opt/pki/Server
mkdir /opt/pki/Client

openssl用コンフィグファイル作成

署名用

/opt/pki/configs/openssl_sign.cnf
[ ca ]
default_ca      = CA_default

[ CA_default ]
dir             = ./
certs           = $dir/certs
crl_dir         = $dir/crl
database        = $dir/index.txt
new_certs_dir   = $dir/newcerts
serial          = $dir/serial
crlnumber       = $dir/crlnumber
crl             = $dir/crl.pem
RANDFILE        = $dir/.rand

name_opt        = ca_default
cert_opt        = ca_default

default_days    = 365
default_crl_days= 30
default_bits    = 2048
default_md      = sha256
preserve        = no
policy          = policy_match

[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints=CA:true
keyUsage = cRLSign,keyCertSign

[ v3_server ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://192.168.0.254/crl/example.net.crl

[ v3_client ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
crlDistributionPoints = URI:http://192.168.0.254/crl/example.net.crl

認証局の構築

RootCA(ルート認証局)

以下の順で生成していきます
1.秘密鍵を生成(=ただの秘密鍵)
2.秘密鍵から証明書署名要求を生成(=ただの秘密鍵から生成した、ただの証明書署名要求)
3.秘密鍵で証明書署名要求に署名(=2.で生成した証明書署名要求に、「CAだよ(とかいろいろ)」のオプション付きで、1.で生成した秘密鍵で署名した、オレオレ証明書)

つまり、この手順は 「自己署名された、CAの機能を有する証明書」を生成する だけである。
オレオレな世界で、「これがルートCAだ!」と認識すれば、これがルートCA証明書になる。

環境の初期化

cd /opt/pki/RootCA
mkdir newcerts
echo "01" > serial
echo "00" > crlnumber
touch index.txt

RootCAの秘密鍵の作成

RootCAの秘密鍵の暗号化パスワードは -passout で与えています。
パスワードは rootcaprivkeypass としています。

openssl genrsa \
 -out RootCA_key.pem \
 -aes256 \
 -passout pass:rootcaprivkeypass \
 2048

RootCAの秘密鍵で、RootCAの証明書署名要求を作成

RootCAの秘密鍵を利用するので -passin でパスワードを与えてます。

openssl req -new \
 -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Root CA" \
 -out RootCA_csr.pem \
 -key RootCA_key.pem \
 -passin pass:rootcaprivkeypass

RootCAの秘密鍵で、RootCAの証明書署名要求に署名する

RootCAの秘密鍵を利用するので -passin でパスワードを与えてます。

openssl ca -config ../configs/openssl_sign.cnf  -batch -extensions v3_ca \
 -out RootCA_crt.pem \
 -in RootCA_csr.pem \
 -selfsign \
 -keyfile RootCA_key.pem \
 -passin pass:rootcaprivkeypass

最後に余計な文字列を取り除くため、 openssl x509 -in 証明書 -out 証明書 しています。
これがRootCAの証明書となります。

openssl x509 -in RootCA_crt.pem -out RootCA_crt.pem

InterCA(中間認証局)

以下の順で生成していきます
1.秘密鍵を生成(=ただの秘密鍵)
2.秘密鍵から証明書署名要求を生成(=ただの秘密鍵から生成した、ただの証明書署名要求)
3.秘密鍵で証明書署名要求に署名(=2.で生成した証明書署名要求に、「CAだよ(とかいろいろ)」のオプション付きで、ルートCAの秘密鍵で署名した、証明書)

つまり、この手順は 「ルートCA(と認識されている証明書)から発行された、CAの機能を有する証明書」を生成する ということである。

環境の初期化

cd /opt/pki/InterCA
mkdir newcerts
echo "01" > serial
echo "00" > crlnumber
touch index.txt

InterCAの秘密鍵の作成

InterCAの秘密鍵の暗号化パスワードは -passout で与えています。
パスワードは intercaprivkeypass としています。

openssl genrsa \
 -out InterCA_key.pem \
 -aes256 \
 -passout pass:intercaprivkeypass \
 2048

InterCAの秘密鍵で、InterCAの証明書署名要求を作成

InterCAの秘密鍵を利用するので -passin でパスワードを与えてます。

openssl req -new \
 -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Intermediate CA" \
 -out InterCA_csr.pem \
 -key InterCA_key.pem \
 -passin pass:intercaprivkeypass 

RootCAの秘密鍵で、InterCAの証明書署名要求に署名をする。

RootCAの秘密鍵を利用するので -passin でパスワードを与えてます。

cd /opt/pki/RootCA
openssl ca -config ../configs/openssl_sign.cnf  -batch -extensions v3_ca \
 -out ../InterCA/InterCA_crt.pem \
 -in  ../InterCA/InterCA_csr.pem \
 -cert RootCA_crt.pem \
 -keyfile RootCA_key.pem \
 -passin pass:rootcaprivkeypass

最後に余計な文字列を取り除くため、 openssl x509 -in 証明書 -out 証明書 しています。
これがInterCAの証明書となります。

cd /opt/pki/InterCA
openssl x509 -in InterCA_crt.pem -out InterCA_crt.pem

さいごに

今後、このPKIを利用したEAP-TLS認証のやり方も整理したいです。

おまけ

一連の作成は以下のコマンドをべろべろー、とコピペすると /opt/pki 配下に環境がつくれます。
コンフィグファイルもヒアドキュメントにしているので、まるまるコピペでOKです。

既存で同ディレクトリが存在している場合には、テキストを修正して別名で作成してください。

もしくは /opt/pkiのデータを別のところに退避してから!
rm /opt/pki -rf で既存をすべて削除してもつくれます。

mkdir -p /opt/pki
mkdir /opt/pki/configs
mkdir /opt/pki/crl
mkdir /opt/pki/RootCA
mkdir /opt/pki/InterCA
mkdir /opt/pki/Server
mkdir /opt/pki/Client

cat <<'EOF' > /opt/pki/configs/openssl_sign.cnf
[ ca ]
default_ca      = CA_default

[ CA_default ]
dir             = ./
certs           = $dir/certs
crl_dir         = $dir/crl
database        = $dir/index.txt
new_certs_dir   = $dir/newcerts
serial          = $dir/serial
crlnumber       = $dir/crlnumber
crl             = $dir/crl.pem
RANDFILE        = $dir/.rand

name_opt        = ca_default
cert_opt        = ca_default

default_days    = 365
default_crl_days= 30
default_bits    = 2048
default_md      = sha256
preserve        = no
policy          = policy_match

[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints=CA:true
keyUsage = cRLSign,keyCertSign

[ v3_server ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://192.168.0.254/crl/example.net.crl

[ v3_client ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
crlDistributionPoints = URI:http://192.168.0.254/crl/example.net.crl
EOF

cd /opt/pki/RootCA
mkdir newcerts
echo "01" > serial
echo "00" > crlnumber
touch index.txt

openssl genrsa -out RootCA_key.pem -aes256 -passout pass:rootcaprivkeypass 2048
openssl req  -new -out RootCA_csr.pem -key RootCA_key.pem -passin pass:rootcaprivkeypass -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Root CA"
openssl ca -config ../configs/openssl_sign.cnf -out RootCA_crt.pem -in RootCA_csr.pem -selfsign -keyfile RootCA_key.pem -passin pass:rootcaprivkeypass -batch -extensions v3_ca
openssl x509 -in RootCA_crt.pem -out RootCA_crt.pem


cd /opt/pki/InterCA
mkdir newcerts
echo "01" > serial
echo "00" > crlnumber
touch index.txt

openssl genrsa -out InterCA_key.pem -aes256 -passout pass:intercaprivkeypass 2048
openssl req  -new -out InterCA_csr.pem -key InterCA_key.pem -passin pass:intercaprivkeypass -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Intermediate CA"
cd /opt/pki/RootCA
openssl ca -config ../configs/openssl_sign.cnf -out ../InterCA/InterCA_crt.pem -in ../InterCA/InterCA_csr.pem -cert RootCA_crt.pem -keyfile RootCA_key.pem -passin pass:rootcaprivkeypass -batch -extensions v3_ca
cd /opt/pki/InterCA
openssl x509 -in InterCA_crt.pem -out InterCA_crt.pem