2013年2月23日土曜日

[SSLの勉強1]:CA構築とサーバ証明書

本などで勉強しても全く頭に入らないので、手を動かして理解する。
いわゆる自己認証・自己証明書作成をやってみる。

  • Mac Book Air
  • Mac OS X 10.8.2
  • OpenSSL 0.9.8
  • Apache 2.2.22

  1. openssl.cfgの作成
  2. ユーザホームディレクトリにpkiというディレクトリを作成し、そこで作業することとする。
    $ mkdir ~/pki
    $ cd ~/pki
    $ sudo cp /System/Library/OpenSSL/openssl.cnf /System/Library/OpenSSL/openssl.cnf.org
    $ vi /System/Library/OpenSSL/openssl.cnf
    今回使用したファイルは以下のとおり。

    openssl.cfg
    #
    # OpenSSL example configuration file.
    # This is mostly being used for generation of certificate requests.
    #
    
    HOME   = .
    RANDFILE  = $ENV::HOME/.rnd
    
    oid_section  = new_oids
    
    [ new_oids ]
    
    ####################################################################
    [ ca ]
    default_ca = CA_default  # The default ca section
    
    ####################################################################
    [ CA_default ]
    
    dir  = ./demoCA
    certs  = $dir/certs
    crl_dir  = $dir/crl
    database = $dir/index.txt
    new_certs_dir = $dir/newcerts
    
    certificate = $dir/cacert.pem 
    serial  = $dir/serial 
    crlnumber = $dir/crlnumber
    crl  = $dir/crl.pem
    private_key = $dir/private/cakey.pem
    RANDFILE = $dir/private/.rand
    
    x509_extensions = usr_cert
    
    name_opt  = ca_default
    cert_opt  = ca_default
    
    default_days = 3650
    default_crl_days= 30
    default_md = sha1
    preserve = no
    
    policy  = policy_match
    
    [ policy_match ]
    countryName  = match
    stateOrProvinceName = match
    organizationName = match
    organizationalUnitName = optional
    commonName  = supplied
    emailAddress  = optional
    
    [ policy_anything ]
    countryName  = optional
    stateOrProvinceName = optional
    localityName  = optional
    organizationName = optional
    organizationalUnitName = optional
    commonName  = supplied
    emailAddress  = optional
    
    ####################################################################
    [ req ]
    default_bits  = 2048
    default_keyfile  = privkey.pem
    distinguished_name = req_distinguished_name
    attributes  = req_attributes
    x509_extensions  = v3_ca 
    
    string_mask = nombstr
    
    [ req_distinguished_name ]
    countryName   = Country Name (2 letter code)
    countryName_default  = JP
    countryName_min   = 2
    countryName_max   = 2
    
    stateOrProvinceName  = State or Province Name (full name)
    stateOrProvinceName_default = Kobe
    
    localityName   = Locality Name (eg, city)
    localityName_default  = Chuo-ku
    
    0.organizationName  = Organization Name (eg, company)
    0.organizationName_default = Internet Widgits Pty Ltd
    
    organizationalUnitName  = Organizational Unit Name (eg, section)
    
    commonName   = Common Name (eg, YOUR name)
    commonName_max   = 64
    
    emailAddress   = Email Address
    emailAddress_max  = 64
    
    [ req_attributes ]
    challengePassword  = A challenge password
    challengePassword_min  = 4
    challengePassword_max  = 20
    
    unstructuredName  = An optional company name
    
    [ usr_cert ]
    basicConstraints=CA:FALSE
    
    nsComment   = "OpenSSL Generated Certificate"
    
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer
    
    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    
    [ v3_ca ]
    subjectKeyIdentifier=hash
    
    authorityKeyIdentifier=keyid:always,issuer:always
    
    basicConstraints = CA:true
    
    [ crl_ext ]
    authorityKeyIdentifier=keyid:always,issuer:always
    
    [ proxy_cert_ext ]
    basicConstraints=CA:FALSE
    
    nsComment   = "OpenSSL Generated Certificate"
    
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer:always
    
    proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
  3. CA構築
  4. $ /System/Library/OpenSSL/misc/CA.sh -newca
    CA certificate filename (or enter to create)
    
    Making CA certificate ...
    Generating a 2048 bit RSA private key
    ...................................................................+++
    ....................................................................................................................................+++
    writing new private key to './demoCA/private/./cakey.pem'
    Enter PEM pass phrase: <== 任意のパスワードを入力
    Verifying - Enter PEM pass phrase: <== もう一度入力
    -----
    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) [JP]:
    State or Province Name (full name) [Kobe]:
    Locality Name (eg, city) [Chuo-ku]:
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, YOUR name) []:noah <== ホスト名(FQDN)入力
    Email Address []:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from /System/Library/OpenSSL/openssl.cnf
    Enter pass phrase for ./demoCA/private/./cakey.pem:  <== 任意のパスワードを入力
    Check that the request matches the signature
    Signature ok
    Certificate Details:
            Serial Number:
                a5:f1:29:54:f4:12:9e:c4
            Validity
                Not Before: Feb 20 16:02:51 2013 GMT
                Not After : Feb 20 16:02:51 2016 GMT
            Subject:
                countryName               = JP
                stateOrProvinceName       = Kobe
                organizationName          = Internet Widgits Pty Ltd
                commonName                = noah
            X509v3 extensions:
                X509v3 Subject Key Identifier: 
                    40:8C:0E:CF:F6:70:8F:09:83:E0:4A:19:31:63:3A:66:3D:9C:23:0E
                X509v3 Authority Key Identifier: 
                    keyid:40:8C:0E:CF:F6:70:8F:09:83:E0:4A:19:31:63:3A:66:3D:9C:23:0E
                    DirName:/C=JP/ST=Kobe/O=Internet Widgits Pty Ltd/CN=noah
                    serial:A5:F1:29:54:F4:12:9E:C4
    
                X509v3 Basic Constraints: 
                    CA:TRUE
    Certificate is to be certified until Feb 20 16:02:51 2016 GMT (1095 days)
    
    Write out database with 1 new entries
    Data Base Updated
    
    作業ディレクトリのdemoCAに認証局証明書(cacert.pem)などができている。
    $ ls ~/pki/demoCA/
    cacert.pem certs  index.txt index.txt.old private
    careq.pem crl  index.txt.attr newcerts serial
    CAの証明書の中身は以下で確認できる。
    $ openssl x509 -in ~/pki/demoCA/cacert.pem -text
  5. サーバの秘密鍵作成
  6. サーバ用のディレクトリを作成して作業。パスワード設定のため入力を求められます。
    $ mkdir ~/pki/server
    $ openssl genrsa -des3 -out ~/pki/server/server.key 1024
    $ ls ~/pki/server
    server.key
    
    これがサーバの秘密鍵になります。
  7. サーバ証明書作成
  8. サーバの証明書に信頼性を持たせるため認証局に署名をしてもらう必要があります。
    これによって、そのサーバが本物であることをクライアントに示すことができます。
    ここでは、認証局も自前なので一般的になんの信頼性もないサーバ証明書になります。(いわゆるオレオレ)

    まずは、署名要求書の作成。CA構築時と全く同じ回答をします。
    $ openssl req -new -days 365 -key ~/pki/server/server.key -out ~/pki/server/csr.pem
    Enter pass phrase for /Users/testuser/pki/server/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) [JP]:
    State or Province Name (full name) [Kobe]:
    Locality Name (eg, city) [Chuo-ku]:
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, YOUR name) []:noah
    Email Address []:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    $ ls ~/pki/server/
    csr.pem  server.key
    このファイルを使って認証局に署名してもらいます。
    $ openssl ca -in ~/pki/server/csr.pem -keyfile ~/pki/demoCA/private/cakey.pem -cert ~/pki/demoCA/cacert.pem -out ~/pki/server/cert.pem
    Using configuration from /System/Library/OpenSSL/openssl.cnf
    Enter pass phrase for /Users/testuser/pki/demoCA/private/cakey.pem:
    Check that the request matches the signature
    Signature ok
    Certificate Details:
            Serial Number:
                bd:48:b8:5b:4c:1c:57:11
            Validity
                Not Before: Feb 23 02:48:56 2013 GMT
                Not After : Feb 21 02:48:56 2023 GMT
            Subject:
                countryName               = JP
                stateOrProvinceName       = Kobe
                organizationName          = Internet Widgits Pty Ltd
                commonName                = noah
            X509v3 extensions:
                X509v3 Basic Constraints: 
                    CA:FALSE
                Netscape Cert Type: 
                    SSL Server
                Netscape Comment: 
                    OpenSSL Generated Certificate
                X509v3 Subject Key Identifier: 
                    0B:BB:C9:A4:6F:8D:93:B8:D3:E1:EA:62:C2:30:FD:46:6B:6A:1F:15
                X509v3 Authority Key Identifier: 
                    keyid:09:18:4F:0E:9D:62:76:25:9D:1D:7F:34:9E:CC:5F:47:C0:DA:41:6B
    
    Certificate is to be certified until Feb 21 02:48:56 2023 GMT (3650 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
    
    一度エラーがでたので、以下の対処を行った。
    $ openssl ca -in ~/pki/server/csr.pem -keyfile ~/pki/demoCA/private/cakey.pem -cert ~/pki/demoCA/cacert.pem -out ~/pki/server/cert.pem
    <省略>
    Certificate is to be certified until Feb 21 02:46:04 2023 GMT (3650 days)
    Sign the certificate? [y/n]:y
    failed to update database
    TXT_DB error number 2
    $ mv ~/pki/demoCA/index.txt ~/pki/demoCA/index.txt.old
    $ touch ~/pki/demoCA/index.txt
    なぜこのエラーがでるのかが、不明。
  9. ApacheのSSL設定
  10. 最低限の設定しかここではしないため、適宜環境・要件に合わせて読み替えてください。
    起動している場合は、Apacheを停止しておく。
    $ sudo apachectl stop
    Apacheに設定する秘密鍵として、パスワード無しの秘密鍵を現在の秘密鍵から作成しておく。
    openssl rsa -in ~/pki/server/server.key -out ~/pki/server/servernopw.key 
    Enter pass phrase for /Users/testuser/pki/server/server.key:
    writing RSA key
    Apacheの設定ファイルを2つ(httpd.conf, httpd-ssl.conf) /etc/apache2/httpd.conf:この行のコメントアウトを外す
    Include /private/etc/apache2/extra/httpd-ssl.conf
    /etc/apache2/extra/httpd-ssl.conf:以下2行でサーバ証明書と秘密鍵を指定する。
    SSLCertificateFile "/Users/testuser/pki/server/cert.pem"
    SSLCertificateKeyFile "/Users/testuser/pki/server/servernopw.key"
    以下にhttpd-ssl.confを載せておく。
    Listen 443
    
    AddType application/x-x509-ca-cert .crt
    AddType application/x-pkcs7-crl    .crl
    
    SSLPassPhraseDialog  builtin
    SSLSessionCache        "shmcb:/private/var/run/ssl_scache(512000)"
    SSLSessionCacheTimeout  300
    SSLMutex  "file:/private/var/run/ssl_mutex"
    
    <VirtualHost _default_:443>
    DocumentRoot "/Library/WebServer/Documents"
    ServerName www.example.com:443
    ServerAdmin you@example.com
    ErrorLog "/private/var/log/apache2/error_log"
    TransferLog "/private/var/log/apache2/access_log"
    
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
    SSLCertificateFile "/Users/testuser/pki/server/cert.pem"
    SSLCertificateKeyFile "/Users/testuser/pki/server/servernopw.key"
    
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "/Library/WebServer/CGI-Executables">
        SSLOptions +StdEnvVars
    </Directory>
    BrowserMatch "MSIE [2-5]" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0
    CustomLog "/private/var/log/apache2/ssl_request_log" \
              "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    </VirtualHost>
    
  11. 接続確認
  12. ブラウザで接続してみる。
    Chromeではこんな感じで警告が出る。「このまま続行」をクリックすると

    サイトが表示される。

おわり

0 件のコメント:

コメントを投稿