手元でクロスルート証明書を作って接続テストする手順のメモ。
openssl ca
とか CA.sh
だといろいろ面倒なので openssl x509
でやっつけです。
# CA1の秘密鍵と証明書(自己署名証明書) openssl req -new -x509 -newkey rsa:2048 -nodes -sha256 -subj /CN=CA1/O=ore -days 365 -keyout ca1.key -out ca1.crt # openssl x509 で署名時、素のままだとCA用の証明書にならないので # X509拡張属性用のファイルを作成(中間証明書用) # # なお req で自己署名証明書を作るときは素のままでもCA用にx509拡張属性が付与される # (そのように openssl.cnf で定義されている) echo "basicConstraints=CA:true" > ca.ext # 中間CAの秘密鍵とCSR openssl req -new -newkey rsa:2048 -nodes -sha256 -subj /CN=inner/O=ore -keyout inner.key -out inner.csr # 中間CA証明書をCA1で署名して発行 openssl x509 -req -days 365 -in inner.csr -out inner.crt -CA ca1.crt -CAkey ca1.key -CAcreateserial -extfile ca.ext # サーバの秘密鍵とCSR openssl req -new -newkey rsa:2048 -nodes -sha256 -subj /CN=localhost/O=ore -keyout sv.key -out sv.csr # サーバ証明書を中間CAで署名して発行 openssl x509 -req -days 365 -in sv.csr -out sv.crt -CA inner.crt -CAkey inner.key -CAcreateserial # CA1からサーバ証明書の検証 openssl verify -show_chain -CAfile ca1.crt -untrusted inner.crt sv.crt #=> sv.crt: OK #=> Chain: #=> depth=0: CN = localhost, O = ore (untrusted) #=> depth=1: CN = inner, O = ore (untrusted) #=> depth=2: CN = CA1, O = ore # CA2の秘密鍵と証明書(自己署名証明書) openssl req -new -x509 -newkey rsa:2048 -nodes -sha256 -subj /CN=CA2/O=ore -days 365 -keyout ca2.key -out ca2.crt # クロスルート用のCSR、秘密鍵にはCA1を指定する openssl req -new -nodes -sha256 -subj /CN=CA1/O=ore -key ca1.key -out cross.csr # クロスルート用の中間証明書をCA2で署名して発行 openssl x509 -req -days 365 -in cross.csr -out cross.crt -CA ca2.crt -CAkey ca2.key -CAcreateserial -extfile ca.ext # CA2からサーバ証明書の検証 openssl verify -show_chain -CAfile ca2.crt -untrusted cross.crt -untrusted inner.crt sv.crt #=> sv.crt: OK #=> Chain: #=> depth=0: CN = localhost, O = ore (untrusted) #=> depth=1: CN = inner, O = ore (untrusted) #=> depth=2: CN = CA1, O = ore (untrusted) #=> depth=3: CN = CA2, O = ore
できました。openssl s_server
でサーバを立てて curl でアクセスしてみます。
まずはクロスルート用中間証明書なしでサーバを実行した場合。
# クロスルート用中間証明書なしでサーバを実行 openssl s_server -accept 8443 -www -chainCAfile inner.crt -cert sv.crt -key sv.key curl https://localhost:8443/ --cacert ca1.crt # OK curl https://localhost:8443/ --cacert ca2.crt # ng
curl 側で cacert に CA1 を指定すれば OK ですが、CA2 だとクロスルート用中間証明書が無いのでダメです。
次にサーバでクロスルート用中間証明書ありでサーバを実行した場合。
# クロスルート用中間証明書ありでサーバを実行 openssl s_server -accept 8443 -www -chainCAfile <(cat cross.crt inner.crt) -cert sv.crt -key sv.key curl https://localhost:8443/ --cacert ca1.crt # OK curl https://localhost:8443/ --cacert ca2.crt # OK
curl 側で cacert に CA1 と CA2 のどちらの場合でも OK になりました。