2011年11月30日水曜日

OAuth1.0のプロトコルを勉強する

OAuth1.0の流れは以下になる。
登場人物として、User(ユーザ)、Consumer、Service Providerの3つがある。
ConumserとService Providerは、事前に信頼関係を構築する必要がある(OpenID仕様みたいに、だれとでも認証連携できるものではない)。

【アクセス権限の設定1】
①ユーザ(ブラウザを使用)は、Consumerに対してサービスを要求する。
②ConsumerのWebsiteでは、Service Providerに対して未認可のRequest Tokenを要求する。Service Providerは、未認可のRequest Tokenを作成し、Consumerに返す。
③Consumerは、Service Providerにユーザをリダイレクトさせる。このとき、未認可のRequest Tokenを送付する。

【アクセス権限の設定2】
①ユーザは、Service Providerと認証する。このとき、未認可のRequest Tokenも送付する。
②ユーザは、Consumerに対し、Service Providerで管理するサービスへのアクセス権限を与える。
③Service Providerは、ユーザをConsumerにリダイレクトさせる。このとき、認可済みRequest Tokenも送付する。

【アクセス権限の委譲】
①ユーザは、Service ProviderからConsumerにリダイレクトされる。
②Consumerは、Service Providerに対して、認可済みRequest TokenをもとにAccess Tokenを要求する。
③Service Providerは、ユーザがConsumerに対してアクセス権限を委譲したかをチェックし、Access Tokenを返す。このとき、Request TokenがAccess Tokenになる。
④Consumerは、Access Tokenを使用してService Providerに対してサービスを要求する。

■未認可のRequest Tokenの内容
(1)リクエスト
Parameter Name Description 
oauth_consumer_keyService Providerにおいて、Consumerと信頼関係を結ぶ際に生成されるConsumerの一意な識別子。
oauth_signature_methodConsumerがRequest Token(リクエスト)を署名する際に使用する署名アルゴリズム。すべてのRequest Token(リクエスト)は、Consumerによって署名され、Service Providerによって署名検証されなけらばならない。OAuthでは以下の署名アルゴリズムをサポートしている。
 HMAC-SHA1, RSA-SHA1, and PLAINTEXT.
oauth_signature上記の署名アルゴリズムによって作成された署名データ。Service ProviderがRequest Token(リクエスト)を検証するために使用する。
oauth_timestampRequest Token(リクエスト)のタイムスタンプ。
oauth_nonceConsumerが作成した一意なランダム文字列。リプライ攻撃を防ぐために使用される。
oauth_versionOAuth 仕様のバージョン(オプション)。
(2)レスポンス
Parameter Name Description 
oauth_tokenRequest Tokenのデータ。
oauth_token_secretConsumerがRequest Tokenを検証するために使用する秘密情報。

■認可済みRequest Tokenの内容
Parameter Name Description 
oauth_token認可済みRequest Tokenのデータ。
oauth_callbackユーザがアクセス権限を委譲した後にリダイレクトされるConsumerのURL。

■Access Tokenの内容
(1)リクエスト
Parameter Name Description 
oauth_consumer_keyService Providerにおいて、Consumerと信頼関係を結ぶ際に生成されるConsumerの一意な識別子。
oauth_tokenRequest Tokenのデータ。
oauth_signature_methodConsumerがRequest Token(リクエスト)を署名する際に使用する署名アルゴリズム。すべてのAccess Token(リクエスト)は、Consumerによって署名され、Service Providerによって署名検証されなけらばならない。OAuthでは以下の署名アルゴリズムをサポートしている。
 HMAC-SHA1, RSA-SHA1, and PLAINTEXT.
oauth_signature上記の署名アルゴリズムによって作成された署名データ。Service ProviderがRequest Token(リクエスト)を検証するために使用する。
oauth_timestampAccess Token(リクエスト)のタイムスタンプ。
oauth_nonceConsumerが作成した一意なランダム文字列。リプライ攻撃を防ぐために使用される。
oauth_version OAuth 仕様のバージョン(オプション)。
(2)レスポンス
Parameter Name Description 
oauth_tokenAccess Tokenのデータ。 
oauth_token_secretConsumerがAccess Tokenを検証するために使用する秘密情報。 

2011年11月29日火曜日

OpenAM 9.5  構築手順

OpenAM9.5の構築手順について説明する。
なお、アプリケーションサーバはGlassfish2.1.1を使用する。

①以下のサイトからGlassfishのインストール媒体(glassfish-installer-v2.1.1-windows.jar )をダウンロードし、インストールする。
http://glassfish.java.net/downloads/v2.1.1-final.html

②Glassfishのドメイン(ポート28080)を作成する。
C:\glassfish\glassfish\bin>asadmin  create-domain  --adminport 24848 --instancep
ort 28080  --savemasterpassword=true --savelogin=true openiddomain
Please enter the admin user name>admin
Please enter the admin password>
Please enter the admin password again>
Please enter the master password [Enter to accept the default]:>
Please enter the master password again [Enter to accept the default]:>
Using port 24848 for Admin.
Using port 28080 for HTTP Instance.
Default port 7676 for JMS is in use. Using 58525
Default port 3700 for IIOP is in use. Using 58526
Default port 8181 for HTTP_SSL is in use. Using 58527
Using default port 3820 for IIOP_SSL.
Using default port 3920 for IIOP_MUTUALAUTH.
Default port 8686 for JMX_ADMIN is in use. Using 58528
Domain being created with profile:developer, as specified by variable AS_ADMIN_P
ROFILE in configuration file.
------ Using Profile [developer] to create the domain ------
XML processing for profile: Base document [C:\glassfish\glassfish\lib\install\te
mplates\default-domain.xml.template]. Profile name [developer]. Processing prope
rty [domain.xml.style-sheets].

The file in given locale [ja_JP] at: [C:\glassfish\glassfish\lib\install\templat
es\locales\ja_JP\index.html] could not be found. Using default (en_US) index.htm
l instead.
Security Store uses: JKS
Domain openiddomain created.
Admin login information for host [localhost] and port [24848] is being overwritt
en with credentials provided. This is because the --savelogin option was used du
ring create-domain command.
Login information relevant to admin user name [admin] for this domain [openiddom
ain] stored at [C:\Users\yasu\Downloads\.asadminpass] successfully.
Make sure that this file remains protected. Information stored in this file will
 be used by asadmin commands to manage this domain.

③作成したドメインを起動する。
C:\glassfish\glassfish\bin>asadmin  start-domain openiddomain
Starting Domain openiddomain, please wait.
Default Log location is C:\glassfish\glassfish\domains\openiddomain\logs\server.
log.
Redirecting output to C:/glassfish/glassfish/domains/openiddomain/logs/server.lo
g
Domain openiddomain is ready to receive client requests. Additional services are
 being started in background.
Domain [openiddomain] is running [Sun GlassFish Enterprise Server v2.1.1 ((v2.1
Patch06)(9.1_02 Patch12)) (build b31g-fcs)] with its configuration and logs at:
[C:\glassfish\glassfish\domains].
Admin Console is available at [http://localhost:24848].
Use the same port [24848] for "asadmin" commands.
User web applications are available at these URLs:
[http://localhost:28080 https://localhost:58527 ].
Following web-contexts are available:
[/web1  /__wstx-services ].
Standard JMX Clients (like JConsole) can connect to JMXServiceURL:
[service:jmx:rmi:///jndi/rmi://yasu-PC:58528/jmxrmi] for domain management purpo
ses.
Domain listens on at least following ports for connections:
[28080 58527 24848 58526 3820 3920 58528 ].
Domain does not support application server clusters and other standalone instanc
es.

④「http://localhost:28080/」にアクセスできることを確認する。

④以下のサイトからOpenAMのインストール媒体(openam_953.war)をダウンロードする。
http://www.forgerock.org/openam.html

⑤「openam_953.war」を「openam.war」に変名する。以下にwarを配備する。
C:\glassfish\glassfish\domains\openiddomain\autodeploy

⑥「http://openam.yasuyasu.com:28080/openam/config/options.htm」にアクセスする。「設定オプション」画面が表示されるため、「カスタム設定」を選択する。

⑦OpenAMの管理ユーザamAdminのパスワードを入力し、「次へ」を押下する。
⑧サーバ情報を入力し、「次へ」を押下する。

⑨「設定データストア」画面が表示される。OpenAMにバンドルされているOpenDSを使用するため、そのまま「次へ」を押下する。
⑩「ユーザデータストア設定」画面が表示される。OpenAMにバンドルされているOpenDSを選択し、「次へ」を押下する。
⑪「サイト設定」画面が表示される。ロードバランサは使用しないを選択し、「次へ」を押下する。
⑫ポリシーエージェントのパスワードを入力し、「次へ」を押下する。

⑬設定の概要画面が表示される。「設定の作成」を押下し、OpenAMのインストールが開始される。

⑭「設定が完了しました」画面が表示される。「http://openam.yasuyasu.com:28080/openam/UI/Login」にアクセスし、管理コンソールにログインできることを確認する。

2011年11月28日月曜日

OpenID  SAMLとの違い

OpenIDとSAMLとの違いについてまとめる。

【参照URL】
http://identitymeme.org/doc/draft-hodges-saml-openid-compare.html

上記の資料に丁寧にまとめられているが、今理解している範囲でまとめると、ポイントは以下になる。
  1. SAML仕様は、運用前に、信頼関係(トラストサークル)を構築する必要がある(SPとIdP間でのメタデータの交換、証明書の交換)。OpenID仕様では、信頼関係を構築する必要がない。どのRPもOPと認証連携できることが原則。なお、OpenID仕様では、OpenIDのプロトコルの中で、OPのエンドポイントURLのディスカバリ、共有鍵の交換を実施している。
  2. 1により、PKI基盤を用いているSAML仕様のほうが、セキュリティ強度が高いと思われる。
  3. SAML仕様では、アサーションという認証情報(XML形式)を規定している。OpenID仕様は、アサーションという形では規定されておらず、キーと値のペアで認証情報をOPとRP間で交換する。
  4. 3により、XML形式で認証情報をやりとりするSAML仕様より、OpenID仕様のほうが処理が軽い(レストフル)と思われる。
  5. SAML仕様は、認証プロトコルのほかに、ユーザの属性情報および認可情報のプロトコルを定義している。OpenID仕様では、認証プロトコル、ユーザの属性情報の交換(CX)を定義しており、認可情報のプロトコルは定義していない。そういう意味で、SAML仕様のほうが、定義範囲が広い。
  6. SAML仕様では、IdPとSP間で仮名IDを使用し、ID連携している(transient/persistent)。一方、OpenID仕様では、グローバルなOpenID(URL)で認証連携している(そもそもID連携していない)。
上記から、高いセキュリティ要件が求められ、かつガチガチに使用するWebサービスの範囲が決まっているお客様に関してはSAML仕様を採用し、mixiやfacebookなどOpenなWebサービス間の認証連携が求められる際にはOpenID仕様を採用して、仕様の使い分けが重要であると考える。

2011年11月24日木曜日

OAuthを勉強する

OAuthは、認証プロトコルではなく、認可情報をやりとりするプロトコルということが分かった。

今の頭の中のイメージは、以下である。

■SAML仕様(認証)
   IdPとSP間で信頼関係を構築し(トラストサークル)、限られた範囲でシングルサインオンする。

■OpenID仕様(認証)
OPとRP間で信頼関係を構築する必要はなく、SAML仕様と比べてよりオープンにシングルサインオンする。

■Liberty ID-WSF仕様(個人情報のやりとり)
Webサービス間で、ユーザの同意を求めながら、個人情報を取得、変更する。

■OAuth仕様(認可)
ConsumerとSP間で、ユーザの同意を求めながら、認可情報を交換し、あるWebサービスが他のWebサービスを使用できるようにする。


2011年11月23日水曜日

Tomcat 6(Windows X64版) Filter機能を使ってみる

Filter機能を使用し、クライアント証明書を検証します。
今回は、クライアント証明書のSubjectNameのCN属性をチェックし、web.xmlの初期パラメタとマッチした値であれば認証OKとします。
また、web.xmlの<filter>要素には、初期パラメタusernameを定義し、認証を許可するCN値を指定します。
なお、Filterを実装するためには、servlet-api.jarを開発環境のビルドパスに設定する必要があります。

①Filterの実装クラスを作成します。ポイントは以下です。
・javax.servlet.Filterインタフェースを継承する必要があります。
・destroy,init,doFilterメソッドは必ず実装する必要があります。
以下は、今回実装したdoFilterメソッドのソースになります。
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

// 初期パラメタの読み込み
String user = config.getInitParameter("username");

if( user == null) {
// エラー処理
throw new ServletException("認証対象のユーザが指定されていません。");
}

log.info("Config User Name=" + user);

// 証明書の取得
X509Certificate certs[] = (X509Certificate[]) request
.getAttribute("javax.servlet.request.X509Certificate");
if (certs == null || certs.length != 1) {
// エラー処理
throw new ServletException("クライアント証明書が指定されていません。");
}
else{
// CNの取得
Principal principal = certs[0].getSubjectDN();
X500Name name = new X500Name(principal.getName());
String cn = name.getCommonName();

log.info("Certificate CN=" + cn);

if(user.equals(cn) == false){
throw new ServletException("認証に失敗しました。");
}
}
// 後のチェーンに渡す
chain.doFilter(request, response);
}


②JAVAクラスを作成したら、JARファイルを作成します。作成したJARをC:\Program Files\Apache Software Foundation\Tomcat 6.0\libに格納します。

③web.xmlに以下のFilter要素を定義します。
-----------------------
  <filter>
    <filter-name>certificatefilter</filter-name>
    <filter-class>com.yasuyasu.filter.cert.CertificateFilter</filter-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>clientuser.yasuyasu.com</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>certificatefilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
----------------------

④Tomcatを再起動します。

⑤https://localhost:8443/sampleappにアクセスできることを確認します。
コンテナログには、以下が出力されており、実装したFilterクラスが呼ばれていることを確認できました。
---------------------------------------------------------------
2011/11/23 22:11:36 com.yasuyasu.filter.cert.CertificateFilter doFilter
情報: Config User Name=clientuser.yasuyasu.com
2011/11/23 22:11:36 com.yasuyasu.filter.cert.CertificateFilter doFilter
情報: Certificate CN=clientuser.yasuyasu.com
---------------------------------------------------------------

ちなみに、認証に失敗した場合、以下のエラーコード500の画面が表示されます。

Tomcat 6(Windows X64版) CLIENT-CERT認証を使ってみる

Tomcatが提供するCLIENT-CERT認証機能を使用して認証してみます。また、JDBCレルムを使用してMySQLからユーザを検索します。
標準のJDBCレルムでは、MySQLのクエリログを参照すると、以下のように、クライアント証明書のSubjectNameでユーザを検索しています。そのため、MySQLにクライアント証明書のSubjectNameでユーザを登録する必要があります。

----------------------------------------------------------------
9 Query SELECT user_password FROM auth_users WHERE user_name ='CN=clientuser.yasuyasu.com, C=jp'
----------------------------------------------------------------

なお、Tomcatにクライアント認証の設定が事前に必要になります。手順は「http://memoyasu.blogspot.com/2011/11/tomcat-6windows-x64ssl.html」を参照してください。

①Webアプリに配備するweb.xmlにおいて、auth-method属性をCLIENT-CERTに設定します。

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Auth</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>admin</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>CLIENT-CERT</auth-method>
  </login-config>


②MySQLにおいて、ユーザとロール用テーブルに認証するユーザを追加します。
mysql> insert into auth_users (user_name, user_password) values
    -> ('CN=clientuser.yasuyasu.com, C=jp', 'pass');
Query OK, 1 row affected (0.09 sec)
mysql> insert into auth_roles (user_name, role_name) values
    -> ('CN=clientuser.yasuyasu.com, C=jp', 'admin');
Query OK, 1 row affected (0.07 sec)

③Tomcatを再起動します。

④「https://localhost:8443/sampleapp」にアクセスできることを確認します。

Tomcat 6(Windows X64版) SSL(クライアント認証)の設定

TomcatのSSL(クライアント認証)の設定手順について説明します。
なお、今回は、Tomcatにクライアント認証を設定する範囲に限定し、Webアプリへの認可の設定まで説明しません。

①OpenSSLを使用し、オレオレ認証局のCA証明書をPEM形式からJKS形式に格納します。
c:\tomcat>keytool -import -file "ca-cert.pem" -trustcacerts -alias ca -keystore
cacerts.jks -storepass password
所有者: CN=ca.yasuyasu.com, C=JP
発行者: CN=ca.yasuyasu.com, C=JP
シリアル番号: f0fc15b1f79fb38b
有効期間の開始日: Tue Nov 22 22:29:35 JST 2011 終了日: Thu Dec 22 22:29:35 JST 2
011
証明書のフィンガープリント:
         MD5:  3E:E5:C6:97:57:AB:44:2C:1C:67:04:39:3C:5C:F0:C6
         SHA1: 66:A8:7E:03:B2:33:5D:4F:80:2A:BA:56:E2:BC:2A:E2:49:02:6C:71
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3

拡張:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 01 6D FE 40 0F CD 30 16   0B B1 E3 69 7E 1B D1 2A  .m.@..0....i...*
0010: 7D 38 CC 22                                        .8."
]
]

#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 01 6D FE 40 0F CD 30 16   0B B1 E3 69 7E 1B D1 2A  .m.@..0....i...*
0010: 7D 38 CC 22                                        .8."
]

]

この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。

②OpenSSLを使用し、クライアント認証用の鍵ペアおよび証明書を作成します。なお、クライアント認証用の証明書は、①のCAで発行した証明書になります。
c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe req -new -keyout "user-client-key.pem
" -out "user-client-req.pem" -days 3600
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
...............++++++
..................++++++
writing new private key to 'user-client-key.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) [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) []:client.yasuyasu.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe x509 -req -days 3600 -CA "ca-cert.pem
"  -CAkey "ca-key.pem" -CAserial "serial.conf" -in "user-client-req.pem" -out "u
ser-client-cert.pem"
Loading 'screen' into random state - done
Signature ok
subject=/C=jp/CN=clientuser.yasuyasu.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:

また、証明書をPEM形式からPKCS#12形式に変換します。ブラウザにインポートするために使用します。
c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe x509 -in "user-client-cert.pem" -out
"user.x509.pem"
c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe pkcs12 -export -inkey "user-client-ke
y.pem" -in "user.x509.pem" -out userclient.p12
Loading 'screen' into random state - done
Enter pass phrase for user-client-key.pem:
Enter Export Password:
Verifying - Enter Export Password:

Tomcatの設定ファイル(server.xml)を開き、以下のように、トラストアストアを指定します。また、clientAuth属性をtrueに設定します(ポイントは太字箇所)。

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="true" sslProtocol="TLS" 
               truststoreFile="c:\tomcat\cacerts.jks"  
               truststorePass="password" 
               keystoreFile="C:\Program Files\Apache Software Foundation\Tomcat 6.0\server.jks" 
               keystorePass="password" />

④Tomcatを再起動します。

⑤ブラウザにクライアント証明書(PKCS#12)をインポートします。


⑥ブラウザを使用し、「https://localhost:8443/sampleapp」にアクセスします。以下の証明書選択画面が表示されるため、証明書を選択してアクセスできることを確認します。


keytool  キーストアからPKCS#12形式の証明書を作成する

キーストアからPKCS#12形式の証明書をエクスポートするコマンドは、以下になります。
・-srckeystoreに、取り出し元のキーストアパスを指定する。
・-destkeystoreに、PKCS#12形式証明書のパスを指定する。
・-deststoretypeに、証明書タイプ PKCS#12を指定する。
・-srcaliasに、-srckeystoreで指定したキーストアから取り出す証明書エイリアス名を指定する。


C:\Windows\system32>keytool -importkeystore -srckeystore "c:\Program Files\Apach
e Software Foundation\Tomcat 6.0\client.jks" -destkeystore "c:\tomcat\user-clien
t.p12" -deststoretype PKCS12 -srcalias client
出力先キーストアのパスワードを入力してください:
新規パスワードを再入力してください:
ソースキーストアのパスワードを入力してください:

Tomcat 6(Windows X64版) MySQLとのSSL通信

TomcatのJDBC認証において、MySQLへの接続をSSL通信にします。
実際には、MySQL Connector/JとMySQL間の通信がSSL通信になります。MySQL Connector/Jの仕様では、サーバ証明書に加えて、クライアント証明書が必要となります(SSL通信では、クライアント認証とサーバ認証が実行されます)。
なお、MySQLのSSL通信(サーバ認証)の設定に関しては、「http://memoyasu.blogspot.com/2011/11/mysql55-ssl.html」を参照してください。


手順の流れは以下になります。
①クライアント証明書と鍵ペアを発行する。
②MySQLの設定ファイル(my.ini)を修正する(クライアント証明書と鍵のパスを指定)。
③MySQLを再起動する。
④Tomcatの設定ファイル(server.xml)を修正する。
⑤Tomcatの起動時のJavaオプションを追加する。
⑥Tomcatを再起動する。


(1)OpenSSLを使用し、MySQL Connector/Jに対する鍵ペアと証明書を発行します。
c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe req -new -keyout "client-key.pem" -ou
t "client-req.pem" -days 3600
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
..........++++++
.................++++++
writing new private key to 'client-key.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) [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) []:client.yasuyasu.com
Email Address []:


Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe x509 -req -days 3600 -CA "ca-cert.pem
"  -CAkey "ca-key.pem" -CAserial "serial.conf" -in "client-req.pem" -out "client
-cert.pem"
Loading 'screen' into random state - done
Signature ok
subject=/C=JP/CN=client.yasuyasu.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
unable to write 'random state'


(2)MySQLの設定ファイル(my.ini)を修正します。太字箇所を追加します。
★パスの区切りは、"\"ではなく、"/"であることに注意!
[client]
ssl-ca=C:/tomcat/ca-cert.pem 
ssl-cert=C:/tomcat/client-cert.pem
ssl-key=C:/tomcat/client-key.pem


(3)MySQLを再起動します。


(4)server.xml(C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf配下)を編集します。connectURL属性に、太字箇所を追加します。


      <Realm className="com.yosiyosi.realm.CustomJDBCRealm"
             driverName="org.gjt.mm.mysql.Driver"
             connectionURL="jdbc:mysql://localhost:3306/bushido?useSSL=true"
             userTable="auth_users" userNameCol="user_name" userCredCol="user_password"
             userRoleTable="auth_roles" roleNameCol="role_name"
             connectionName="root" connectionPassword="password"/>


(5)keytoolコマンドを使用し、CA証明書をPEM形式からDER形式に変換します。
c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe x509 -outform DER -in ca-cert.pem -out ca.cert

c:\tomcat>keytool -import -file ca.cert -keystore server.jks -alias ca
キーストアのパスワードを入力してください:
新規パスワードを再入力してください:
所有者: CN=ca.yasuyasu.com, C=JP
発行者: CN=ca.yasuyasu.com, C=JP
シリアル番号: f0fc15b1f79fb38b
有効期間の開始日: Tue Nov 22 22:29:35 JST 2011 終了日: Thu Dec 22 22:29:35 JST 2
011
証明書のフィンガープリント:
         MD5:  3E:E5:C6:97:57:AB:44:2C:1C:67:04:39:3C:5C:F0:C6
         SHA1: 66:A8:7E:03:B2:33:5D:4F:80:2A:BA:56:E2:BC:2A:E2:49:02:6C:71
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3


拡張:


#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 01 6D FE 40 0F CD 30 16   0B B1 E3 69 7E 1B D1 2A  .m.@..0....i...*
0010: 7D 38 CC 22                                        .8."
]
]


#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2147483647
]


#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 01 6D FE 40 0F CD 30 16   0B B1 E3 69 7E 1B D1 2A  .m.@..0....i...*
0010: 7D 38 CC 22                                        .8."
]


]


この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。



(6)keytoolコマンドを使用し、クライアント証明書をPEM形式からDER形式に変換します。


c:\tomcat>c:\OpenSSL-Win64\bin\openssl.exe x509 -outform DER -in client-cert.pem
 -out client.cert
c:\tomcat>keytool -import -file client.cert -keystore client.jks -alias client
キーストアのパスワードを入力してください:
新規パスワードを再入力してください:
所有者: CN=client.yasuyasu.com, C=JP
発行者: CN=ca.yasuyasu.com, C=JP
シリアル番号: 5
有効期間の開始日: Wed Nov 23 00:22:25 JST 2011 終了日: Fri Oct 01 00:22:25 JST 2
021
証明書のフィンガープリント:
         MD5:  15:78:E2:00:B1:A0:BF:03:AB:47:1B:CF:91:B0:E6:99
         SHA1: 10:0C:11:64:CE:A2:41:FB:35:1D:13:16:29:E8:CB:EA:C6:14:12:C5
         署名アルゴリズム名: SHA1withRSA
         バージョン: 1
この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。




(7)Tomcatの起動時に、Javaのオプションとして以下を追加します。


-Djavax.net.ssl.keyStore=c:\tomcat\client.jks
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=c:\tomcat\server.jks
-Djavax.net.ssl.trustStorePassword=password

(8)Tomcatを再起動します。
「http://127.0.0.1:8080/sampleapp/sample.html」にアクセスし、FORM認証が成功することを確認します。




■補足■
SSL通信でエラーが発生した場合には、Javaオプションに以下を設定してTomcatを起動します。SSL通信する際の詳細なログが標準出力に出力されて便利です。


-Djavax.net.debug=all


<出力例>

2011-11-23 01:42:15 Commons Daemon procrun stdout initialized
trustStore is: c:\tomcat\server.jks
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=ca.yasuyasu.com, C=JP
  Issuer:  CN=ca.yasuyasu.com, C=JP
  Algorithm: RSA; Serial number: 0xf0fc15b1f79fb38b
  Valid from Tue Nov 22 22:29:35 JST 2011 until Thu Dec 22 22:29:35 JST 2011


trigger seeding of SecureRandom
done seeding SecureRandom
***
found key for : server
chain [0] = [
[
  Version: V3
  Subject: CN=yasu.hoge.com, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=jp
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5


  Key:  Sun RSA public key, 1024 bits
  modulus: 122242012982209662923393081262187509019889149396697912939693246792421045784628744532131386668778037133171905458919922944159056873911220455399771810893972594625969976059362725970167560234465556141102327452863823309180840502041205195494958180017978965410060359966763326464061148776167266441521233069679259172879
  public exponent: 65537
  Validity: [From: Mon Oct 17 21:34:43 JST 2011,
               To: Sat Apr 14 21:34:43 JST 2012]
  Issuer: CN=yasu.hoge.com, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=jp
  SerialNumber: [    4e9c20e3]


]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 60 CA 23 E8 32 1B A8 73   51 6F A8 AE A2 BE E3 92  `.#.2..sQo......
0010: 0F BD 05 FF AB B0 C3 EE   17 62 53 49 AF 1E F1 EF  .........bSI....
0020: 36 FC F5 79 75 FF A3 44   AA 8D 4A C4 91 47 1A A5  6..yu..D..J..G..
0030: 05 60 8F 2A E0 FE 07 52   13 1C BD 09 11 10 92 74  .`.*...R.......t
(省略)