認証局を作ろう!

このサイトは、apache + modssl なんちゅーもので動いている。
で、これは FreeBSD の ports から入れたのだが、そのときは make certificate とかなんとかやって、サンプルの認証を行うようになっていたらしい。
で、その証明書の有効期限が切れたのと、人に聞かれたので、新しい証明書を作りがてら、認証局の真似事もしてみることにした。

  1. まず、最初に認証局の秘密鍵を作った。
    % openssl genrsa -des3 -out ca.key 1024
    Generating RSA private key, 1024 bit long modulus
    ...................++++++
    ....++++++
    e is 65537 (0x10001)
    Enter pass phrase for ca.key:
    Verifying - Enter pass phrase for ca.key:
    
    これで、ca.key ファイルができる。パスフレーズは、適当に入れた。(後で使うので忘れないように)

  2. 続いて、自分でサインした証明書を作る。
    % openssl req -new -x509 -days 365 -key ca.key -out ca.crt
    Enter pass phrase for ca.key:  ←先ほど入れたパスフレーズ
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:JP  ←国名。日本ならJP
    State or Province Name (full name) [Some-State]:Kanagawa  ←県名
    Locality Name (eg, city) []:Yokohama  ←市など
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Wizard limit  ←組織の名前
    Organizational Unit Name (eg, section) []:CA  ←組織の部課名など
    Common Name (eg, YOUR name) []:www.wizard-limit.net  ←認証局の名前
    Email Address []:root@wizard-limit.net  ←管理者のメールアドレス
    
    これで、ca.crt ファイルができる。このファイルは、これから認証を与えるWEBサーバの管理者に配布するもの。
    とりあえず、認証局の準備はここまで。

  3. 続いて、認証する対象となるWEBサイトの鍵を作る。
    % openssl genrsa -des3 -out server.key 1024
    Generating RSA private key, 1024 bit long modulus
    ........++++++
    ......++++++
    e is 65537 (0x10001)
    Enter pass phrase for server.key:
    Verifying - Enter pass phrase for server.key:
    
    これで、server.key ができる。

  4. 続いて、証明書の発行要求を作る。
    % openssl req -new -key server.key -out server.csr
    Enter pass phrase for server.key:
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:JP
    State or Province Name (full name) [Some-State]:Kanagawa
    Locality Name (eg, city) []:Yokohama
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Wizard limit
    Organizational Unit Name (eg, section) []:www
    Common Name (eg, YOUR name) []:www.wizard-limit.net
    Email Address []:webmaster@wizard-limit.net
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    
    これで、server.csr ができる。
    後は、このserver.csr を認証局に送ると、署名して返してくれる。しかし、今は自分が認証局もやっているので、次のステップに進む。
    注:ここで、Organization NameとOrganizational Unit Name の組み合わせが、caのものと異なるようにしないと、次のsign.shでエラーが出る。エラーメッセージを見てもわからないのでかなりはまった。

  5. サインする。
    % ./sign.sh server.csr
    CA signing: server.csr -> server.crt:
    Using configuration from ca.config
    Enter pass phrase for ./ca.key:
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName           :PRINTABLE:'JP'
    stateOrProvinceName   :PRINTABLE:'Kanagawa'
    localityName          :PRINTABLE:'Yokohama'
    organizationName      :PRINTABLE:'Wizard limit'
    organizationalUnitName:PRINTABLE:'www'
    commonName            :PRINTABLE:'www.wizard-limit.net'
    emailAddress          :IA5STRING:'webmaster@wizard-limit.net'
    Certificate is to be certified until Mar 27 05:31:42 2004 GMT (365 days)
    Sign the certificate? [y/n]:y
    
    
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Data Base Updated
    CA verifying: server.crt <-> CA cert
    server.crt: OK
    
    ちなみに、sign.sh は mod_ssl のソースの pkg.contrib ディレクトリにある。中では openssl ca を呼び出しているのだが、これを手でやると大変なのでこのスクリプトを使う(と、参考にしたサイトに書いてあった)
    これで、server.crt ができるので、server.csr を送ってきたWEBサーバのサイト管理者に送る。(もちろんここでは自分だ)

  6. apache の設定 WEBサーバの管理者に必要なファイルは、ca.crt, server.key, server.crt の3つ。httpd.conf で SSL の設定が正しく済んでいれば、以下の3行を変更すれば動くはず。
    SSLCertificateFile /usr/local/etc/apache/ssl/server.crt  ← server.csr のパス
    SSLCertificateKeyFile /usr/local/etc/apache/ssl/server.key  ← server.key のパス
    SSLCertificateChainFile /usr/local/etc/apache/ssl/ca.crt  ← ca.crt のパス
    
    とりあえず、ここまでの設定で apache を起動し、ブラウザに CA の方の証明書をインストールしたところ、署名したWEBサイトはノーチェックで行けるようになった。
    しかし、認証局の方の設定がまだわからないので、ca.key や sign.sh で作成された ca.db.* などのファイルを誰も参照していない・・・(汗)


  7. おまけ
    ローカルサイトで、普通にhttps通信ができれば良いだけの場合、わざわざこのような手順を踏んだり、認証局にお金を払ったりする必要はない。(ブラウザに毎回警告が出ても、通信路はちゃんと暗号化されるから大丈夫だ)
    このページの手順3, 4を実行した後、自分の秘密鍵でサインすることでも crt ファイルを作ることができる。
    % openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 365
    Signature ok
    subject=/C=JP/ST=Kanagawa/L=Yokohama/O=Wizard limit/OU=www/CN=www.wizard-limit.net/emailAddress=webmaster@wizard-limit.net
    Getting Private key
    Enter pass phrase for server.key:
    
  8. おまけその2
    手順3でパスフレーズを入れてしまうと、apacheの起動時にパスフレーズの入力を求められる。
    これを入力しなくて済むようにするには、以下のようにしてやると良い。
    % openssl rsa -in server.key -out server_.key
    read RSA key
    Enter PEM pass phrase:
    writing RSA key
    % mv server_.key server.key
    
  9. おまけその3
    できあがったcaの証明書は、httpsのページを見るときに出るダイアログからブラウザにインストールできるが、一応ダウンロードできるようにする場合は、以下のようにする。
    % openssl x509 -inform pem -in ca.crt -outform der -out ca.der
    
    この、ca.derをhttpでダウンロードできるところに置けば良い。
    と、言うわけで、このサイトの証明書

    ちなみに、.derが証明書であるとブラウザに認識させるためには、apacheのhttpd.confに以下の行がある必要がある。
    AddType application/x-x509-ca-cert .der
    

false@wizard-limit.net