目次

概要

javax.net.SSLServerSocketを利用するための証明書を作成する。
以下の条件で証明書を生成・署名して、JVMから利用可能にする。
  • 1. CA局はOpenSSLで用意する。
  • 2. JVMで利用する鍵ペア(秘密鍵/公開鍵証明書要求)はOpenSSLで生成する。
  • ※keytoolでCSRを発行した場合はこちら
  • 3. 1.のCA局で2.の公開鍵証明書要求に署名する

環境

PowerBook? G4を検証環境とした。
% uname -a (うそっぽいw)
Darwin Kernel Version 7.6.0: 
PDT 2004; root:xnu/xnu-517.9.4.obj?1/RELEASE_PPC  Power Macintosh powerpc 
% java -version
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-141.3)
Java HotSpot(TM) Client VM (build 1.4.2-38, mixed mode)
% openssl version
OpenSSL 0.9.7b 10 Apr 2003

手順

CA局の作成(OpenSSLを利用)

  • 1.OpenSSL付属のスクリプトでCA局の作成
  • 今回は、CA.pl -newcaで作成した。
    CA局の証明書パスフレーズは hogeで設定した。
    自己署名した証明書の内容は省略。以下は demoCA/cacert.pemの中身。
  
 -----BEGIN CERTIFICATE-----
 MIIDaDCCAtGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCSlAx
 DjAMBgNVBAgTBVRva3lvMQ4wDAYDVQQHEwVZb3VnYTEOMAwGA1UEChMFU3VuS0sx
 DDAKBgNVBAsTA0NTTzEUMBIGA1UEAxMLTWFzYW1pIEl0b3UxIjAgBgkqhkiG9w0B
 CQEWE21hc2FtaS5pdG91QHN1bi5jb20wHhcNMDQxMTE2MDQyNzA3WhcNMDUxMTE2
 MDQyNzA3WjCBhTELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBVRva3lvMQ4wDAYDVQQH
 EwVZb3VnYTEOMAwGA1UEChMFU3VuS0sxDDAKBgNVBAsTA0NTTzEUMBIGA1UEAxML
 TWFzYW1pIEl0b3UxIjAgBgkqhkiG9w0BCQEWE21hc2FtaS5pdG91QHN1bi5jb20w
 gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL+T2z+68QjHSGrapITUJZv8ed14
 Yujr5tSmJS8HWozRsuSJ19JEKHSL9ENOqPHZQ2KZYsKaFyF4CLhY3ltRb6lmX878
 A8uhVuEyJoUm1wKDS41O0bu6GMiQCzsUcTCQLlREiglERx5SrqRFdlWg+aOThbKD
 1p/QUTv/Ahlc0DlTAgMBAAGjgeUwgeIwHQYDVR0OBBYEFLH/7AeKyYqVl/dul4Qi
 ZfzSQv5dMIGyBgNVHSMEgaowgaeAFLH/7AeKyYqVl/dul4QiZfzSQv5doYGLpIGI
 MIGFMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xDjAMBgNVBAcTBVlvdWdh
 MQ4wDAYDVQQKEwVTdW5LSzEMMAoGA1UECxMDQ1NPMRQwEgYDVQQDEwtNYXNhbWkg
 SXRvdTEiMCAGCSqGSIb3DQEJARYTbWFzYW1pLml0b3VAc3VuLmNvbYIBADAMBgNV
 HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBADKhdbYETlHfhDMR1arr8wU0BtM3
 Okn10jaP3qOFA7ec+CWfCp1ua4qbbFj9JUdegJv4mLU67cVvEBQqy7TEiwMqHYkE
 -----END CERTIFICATE-----

keytoolのKeyStore?の作成(keytoolを利用)

KeyStore?ファイルの作成とCA局の証明書をimport
% keytool -import -keystore
./ServerKeyStore.11162004
キーストアのパスワードを入力してください:  hogehoge
-----BEGIN CERTIFICATE-----
 /* 同上なので省略 */
-----END CERTIFICATE-----
所有者: 微妙なので削除w
実行者: 同上
シリアル番号: 0
有効日: Tue Nov 16 13:27:07 JST 2004 有効期限: Wed Nov 16 13:27:07 JST 2005
証明書のフィンガープリント:
         MD5:  42:75:51:26:BB:71:10:FF:64:9D:E0:68:33:F4:E7:41
         SHA1: 3E:39:E0:43:68:2F:E6:8A:5C:AE:1C:B3:34:CA:40:87:CE:CF:AC:5E
この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。
% ls
ServerKeyStore.11162004
  • -keystoreオプションで指定したkeystoreが存在しない場合、KeyStore?は新規作成される。デフォルトのKeyStore?は ~/.keystoreである。

秘密鍵と証明諸要求の作成(OpenSSLを利用)

新規に証明書要求を作成する。opensslのgenrsa/reqコマンドを用いる。
以下の作業では秘密鍵(serv.key)と証明書要求(serv.pem)を作成している。

秘密鍵の作成

 % openssl genrsa -des3 -out serv.key 1024
 Generating RSA private key, 1024 bit long modulus
 .....++++++
 ...++++++
 e is 65537 (0x10001)
 Enter pass phrase for serv.key: (パスフレーズはとりあえず hogehoge )
 Verifying - Enter pass phrase for serv.key:
 

パスフレーズの解除(option)

 % openssl rsa -in serv.key -out servNopass.key
 Enter pass phrase for serv.key: (hogehogeと入力)
 writing RSA key
 

証明書要求の作成

 % openssl req -new -days 365 -key serv.key -out serv.pem
 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]:
 Locality Name (eg, city) []:
 Organization Name (eg, company) [Internet Widgits Pty Ltd]:
 Organizational Unit Name (eg, section) []:
 Common Name (eg, YOUR name) []:
 Email Address []:mage@ld.oops.jp
 
 Please enter the following 'extra' attributes
 to be sent with your certificate request
 A challenge password []:
 An optional company name []:

署名(OpenSSLを利用)

上記で作製したCAでsignする。
今回の証明書要求の内容だと、default状態では署名できないので設定を変える必要がある。

openssl.cnfの修正

  • 1. 署名のpolicy設定
  • default状態では署名する証明書要求の条件は厳しいので、 ゆるゆるの状態にしておく。以下は openssl.cnfよりの抜粋。
 # A few difference way of specifying how similar the request should look
 # For type CA, the listed attributes must be the same, and the optional
 # and supplied fields are just that :-)
 #policy         = policy_match (これがデフォルト)
 policy          = policy_zaru
  
 # For the CA policy
 # (デフォルトポリシーだとCNからOまで一緒じゃないとsign不可)
 [ policy_match ]
 countryName             = match
 stateOrProvinceName     = match
 organizationName        = match
 organizationalUnitName  = optional
 commonName              = supplied
 emailAddress            = optional
  
 # 今回のためのザル policy
 [ policy_zaru]
 countryName             = match
 stateOrProvinceName     = optional
 organizationName        = optional
 organizationalUnitName  = optional
 commonName              = supplied
 emailAddress            = optional
  • 2. x509v3 extension設定
  • CSRに署名する際には、x509v3 extensionを適正に設定する必要がある。 Netscape Certificate Extensionの設定はデフォルト状態では SSLサーバのための署名を行うように設定されている。
    設定ファイル上は nsCertTypeで設定されてする箇所がこれにあたる。
    nsCertTypeを用途に合わせて、server(0x40)か client(0x80)に設定する。

署名

openssl caコマンドを行うだけ。
 % openssl ca -config openssl.cnf -in serv/serv.pem -out singed-serv.pem

PKCS#12形式でPrivate/Public keyのexport(OpenSSLを利用)

openssl pkcs12コマンドを利用する。

pkcs12への変換

% openssl pkcs12 -export -inkey servNoPass.key -in singed-serv.pem -certfile \
cacert.pem -out serv.p12
Enter Export Password: (exportと入力)
Verifying - Enter Export Password: (exportと入力)

内容の確認

openssl pkcs12 -infoで ファイルの中身を確認する際には2回チェックがある。
  • encryptされたpkcs12ファイルの解凍
  • これは上記の export passwordの入力をすればよい。
  • 秘密鍵の復号
  • 実装上の縛りか、passを無効化していても、必ず確認される。何でもいいので 4文字以上の入力を二回すればいい。
    なお、以下の条件でここのvalidateが失敗する。
 1. 入力した2回が一致しない場合
 2. 入力した2回が4文字未満の場合
なお、keyにpassが設定されているならば、適正なpassを入力する事。
 % openssl pkcs12 -in serv.p12 -info
 Enter Import Password: (exportと入力)
 MAC Iteration 2048
 MAC verified OK
 PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
  /* 以下 serv.pemの内容を省略 */
 Certificate bag
 Bag Attributes: <No Attributes>
  /* 以下 cacert.pemの内容を省略 */
 PKCS7 Data
  /* 以下 servNoPass.keyの内容 */
 Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
 Bag Attributes
     localKeyID: B5 63 21 15 FD C3 38 0C 45 59 3D FC 49 2C B0 68 E3 90 A6 0E 
 Key Attributes: <No Attributes>
 Enter PEM pass phrase: (とりあえず testと入力)
 Verifying - Enter PEM pass phrase: (とりあえず testと入力)
 -----BEGIN RSA PRIVATE KEY-----
 Proc-Type: 4,ENCRYPTED
 DEK-Info: DES-EDE3-CBC,5FFFEB1CCCAADF08
  /* 以下 servNoPass.keyの内容を省略 */

公開鍵証明書のimport(keytoolを利用)

keytoolを利用する場合は $JAVA_HOME/lib/security/java.securityの keystore.typeを jksから pkcs12に変更するとKeyStore?の形式をSystem Wideに変更できる。
KeyStore?に対して -storetypeオプションを指定することで、 実行時にKeyStore?のタイプを指定可能である。

CA局証明書無しの場合

今回の手続きとしては最初にCA局の証明書をkeystoreに入れてあるので、 秘密鍵/公開鍵証明書だけをkeystoreに格納すればよい。
importの手順に関してはこちらを参照のこと。

CA局証明書同梱の場合(opt)

配布の形態を考えると、CA局の証明書が同梱されているものと思われる。
この場合は先に作製したPKCS#12形式のファイルを KeyStore?とする。

利用時の注意事項

SSL利用時には -Djavax.net.ssl.keystoreオプションでファイルを指定する必要がある。
java.securityファイルのkeystore.typeを変更している場合、 trustStoreもデフォルト($JAVA_HOME/lib/security/cacerts)が 利用できないため、-Djavax.net.ssl.trustStoreか-Djavax.net.ssl.trustStoreType オプションの指定が必須である。
利用に際しては、以下のPropertyを適切に指定しておくことが望ましい。
Property指定する値明示的な設定を推奨補足
javax.net.ssl.keyStoreキーストア(秘密鍵格納先)の場所サーバ秘密鍵の格納先
javax.net.ssl.keyStoreTypepkcs12デフォルトはjks(JSSE独自)である。
javax.net.ssl.keyStorePasswordPKCS#12を作った時のpass phrase
javax.net.ssl.trustStoreトラストストア(信用する証明書)の場所$JAVA_HOME/lib/security/cacertファイルがデフォルトのトラストストア(jks形式)であり、ここには沢山の証明書が詰まっている。
javax.net.ssl.trustStoreTypekeyStoreTypeに同じ。JDK同梱のtrustStoreはjksである。
javax.net.ssl.trustStorePasswordデフォルトは無し

keytoolの問題点

JDK備え付けのkeytoolは便利だが、上記のような想定されていない(と思われる)用途では以下のような問題点がある。
  • 1. opensslで作製した秘密鍵をjks形式のkeystoreにimportする方法は無い
  • keytoolの機能に秘密鍵をimport/exportする機能は無いため、keystoreを 直接操作する(=適当に実装する)以外の方法は無い。

参考

参考リンク


Last-modified: 2008-04-14 16:26:17