1. Qiita
  2. 投稿
  3. openssl

クライアント証明書を要求するサイトの構築(Apache+OpenSSL)その1

  • 48
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

参考にしたサイト

クライアント証明書を要求するサイトの構築(Apache+OpenSSL)その2 - Qiita [キータ]書きました。

ランダムパスワード生成方法

  • 多くのパスワードを作る必要があるのでpwgen使うと便利。

サーバ証明書の作成

1. 独自認証局の秘密鍵、ルート証明書(CA)の作成

  • C: 国名 (JP)
  • ST: 都道府県 (Tokyo)
  • O: 会社名 (My Company Ltd)
  • OU: 部署名 (sales)
  • CN:サーバーのドメイン名 (mycompany.co.jp:8000等。証明書の表示名に使われます。)
cd /opt/
mkdir -p demoCA/{private,newcerts}
cd demoCA
echo 01 > serial
openssl req \
  -x509 \
  -days 3650 \
  -newkey rsa:2048 \
  -keyout private/cakey.pem \
  -out cacert.pem \
  -subj "/C=JP/ST=Tokyo/O=localhost/OU=test/CN=$(hostname)"
# cakey.pem のパスワードを入力
file 備考
private/cakey.pem 秘密鍵
cacert.pem 認証局(CA)証明書

2. 秘密鍵とサーバ署名要求(CSR)の作成

サーバ証明書
cd /opt/demoCA/

openssl req \
  -newkey rsa:2048 \
  -keyout newkey.pem \
  -out newreq.pem \
  -subj "/C=JP/ST=Tokyo/O=localhost/OU=test/CN=$(hostname)"

* newkey.pem のパスワードを入力
file 備考
newkey.pem ホストキー(パスワードあり)
newreq.pem ホスト証明書

3.パスワードなしのホストキー作成

apacheに組みこむ用。

/opt/demoCA/
openssl rsa -in newkey.pem -out nokey.pem
# newkey.pem のパスワードを入力

4. CSRへの署名

/opt/demoCA/
touch index.txt
cd /opt

openssl ca \
  -in demoCA/newreq.pem \
  -days 3650 \
  -out demoCA/cert.pem \
  -notext
# /opt/demoCA/private/cakey.pem のパスワードを入力

5. openssl.cnfを編集

cd /opt/demoCA
cp -a /etc/ssl/openssl.cnf .

openssl.cnfを書き換える

/opt/demoCA/openssl.cnf
 ####################################################################
 [ CA_default ]
-dir        = ./demoCA      # Where everything is kept
+dir        = /opt/demoCA       # Where everything is kept

-default_days   = 365           # how long to certify for
+default_days   = 3650          # how long to certify for

-default_md     = default   # 署名アルゴリズム | 署名ハッシュアルゴリズム
+default_md     = sha256

 [ policy_match ]
-organizationalUnitName  = optional
+organizationalUnitName  = supplied
-commonName              = supplied
+commonName              = optional

 [ policy_anything ]
-organizationalUnitName  = optional
+organizationalUnitName  = supplied
-commonName              = supplied
+commonName              = optional

 [ req_distinguished_name ]
-countryName_default        = AU                       # サブジェクト -> C
+countryName_default        = JP

-stateOrProvinceName_default    = Some-State           # サブジェクト -> S
+stateOrProvinceName_default    = Tokyo

-0.organizationName_default = Internet Widgits Pty Ltd # サブジェクト -> O
+0.organizationName_default = localhost # My Company Ltd

-organizationalUnitName     = Organizational Unit Name (eg, section) # サブジェクト -> OU
+organizationalUnitName     = Organizational Unit Name (eg, username)

6. 証明書失効リスト用

echo "00" > crlnumber

クライアント用証明書の作成

p12キーの生成

各クライアントに配布する用にp12キーを生成。
クライアント名.p12 のパスワードも伝える必要がありますので、クライアント名.p12.txtにパスワードを書いときます。
このp12キーはクライアントの端末にインストールすることになります。

/opt/demoCA/create_cert.sh
#!/bin/sh
set -eux

CLNT=$1
CA_ROOT=/opt/demoCA
REPOS=${CA_ROOT}/repository
mkdir -p $REPOS/${CLNT}

# key : 秘密鍵生成
openssl genrsa -rand /var/log/messages -out ${REPOS}/${CLNT}/${CLNT}-client.key -des3 2048

# key -> csr : 署名要求
openssl req -new -key ${REPOS}/${CLNT}/${CLNT}-client.key -out ${REPOS}/${CLNT}/${CLNT}-client.csr -config openssl.cnf 

# csr -> pem : 署名(Base64形式)
openssl ca -config openssl.cnf -keyfile ${CA_ROOT}/private/cakey.pem -cert ${CA_ROOT}/cacert.pem -in ${REPOS}/${CLNT}/${CLNT}-client.csr -out ${REPOS}/${CLNT}/${CLNT}-client.pem

# pem -> crt : 証明書
openssl x509 -in ${REPOS}/${CLNT}/${CLNT}-client.pem -out ${REPOS}/${CLNT}/${CLNT}-client.crt

# crl (失効リスト更新)
openssl ca -config openssl.cnf -gencrl -out ${CA_ROOT}/ca.crl -keyfile ${CA_ROOT}/private/cakey.pem -cert ${CA_ROOT}/cacert.pem -verbose -crldays 3650

# p12 (webブラウザ用。秘密鍵と公開鍵(証明書)を PKCS #12ファイルにまとめる)
openssl pkcs12 -export -in ${REPOS}/${CLNT}/${CLNT}-client.crt -inkey ${REPOS}/${CLNT}/${CLNT}-client.key -out ${REPOS}/${CLNT}/${CLNT}-client.p12 -certfile ${CA_ROOT}/cacert.pem -name 'demoCA Client Cert' -caname 'demoCA'

#p12.txt (p12のパスワードをtxtに保存)
echo -n "enter ${CLNT}.p12 pass : "
read P12PASS
echo ${P12PASS} > ${REPOS}/${CLNT}/${CLNT}-client.p12.txt

途中パスワード入力を間違えると手動でのリカバリーが大変なのでバージョン管理で戻せるようにする。

git init
git add -A && git commit -m "init"
使い方
create_cert.sh kitamura
# repository/ユーザ名/ユーザ名.key のパスワード
# repository/ユーザ名/ユーザ名.p12 のパスワード
# private/cakey.pemのパスワード
git add -A && git commit -m "add: クライアント名"

Apacheの設定

sudo sh -c "echo ServerName $HOSTNAME" >> /etc/apache2/httpd.conf
/etc/apache2/sites-available/default-ssl
SSLCertificateFile    /opt/demoCA/cert.pem
SSLCertificateKeyFile /opt/demoCA/nokey.pem
SSLCACertificateFile  /opt/demoCA/cacert.pem
<Location /owncloud/>
SSLVerifyClient require
</Location>
sudo ln -s /etc/apache2/mods-{available,enabled}/ssl.conf
sudo ln -s /etc/apache2/mods-{available,enabled}/ssl.load
sudo ln -s /etc/apache2/sites-available/default-ssl \
           /etc/apache2/sites-enabled/001-default-ssl
sudo apachectl configtest
sudo /etc/init.d/apache2 restart

pemファイルの変換

openssl pkcs12 -export -in [input_file] -out [output_file]
openssl x509 -in [input_file] -inform PEM -text -noout