TLS 接続のクライアント認証のために、クライアント側で (TrustStore ではなく) KeyStore として PKCS#11 トークン (スマート カード) を使用しようとしています。ただし、SSL ハンドシェークはSSLException
次のメッセージで失敗します。
予期せず、privatekey は RSA 秘密鍵ではありません。
スマート カードの秘密キーと証明書のペアは RSA キーであるため、これは当てはまりません。スマート カードを JSSE の KeyStore として使用するための構成が不足していますか?
ここに私の設定の詳細があります:
最初に、Sun PKCS#11 Provider を構成して、スマート カードとインターフェイスする 'ActivCard' dll で動作するようにしました。Sun PKCS#11 Provider 構成ファイルには、'name' 属性と 'library' 属性だけが含まれています。
SunPKCS#11 プロバイダのインスタンス化は次のようになります。
java.security.AuthProvider provider =
new sun.security.pkcs11.SunPKCS11.SunPKCS11(<Configuration file>);
次に、java.security.KeyStore
スマート カードからのオブジェクトのインスタンス化は、次のコードを使用して行われます。
KeyStore.ProtectionParameter thePasswordProtection =
new KeyStore.PasswordProtection( null );
KeyStore.Builder theBuilder =
KeyStore.Builder.newInstance( "PKCS11", provider, thePasswordProtection );
java.security.KeyStore theKeyStore = theBuilder.getKeyStore();
さらに、このインスタンス化されたは、以下のコードを使用して JSSE で使用されるKeyStore
ようにするために使用されます。KeyManagerFactory
KeyManagerFactory kmf = javax.net.ssl.KeyManagerFactory.
getInstance( "SunX509", "SunJSSE" );
kmf.init( theKeyStore, <smart card pin> );
この KeyManagerFactory は、SSLSocket のインスタンス化に使用される SSLContext の初期化に使用されます。
Oracle の JSSERefGuide for Java 6 の指示に従って、これが機能するために必要なすべてです。キーストアをプログラムで使用する際に以下のシステム プロパティを設定する必要はありませんが、システム プロパティも追加してみました。
javax.net.ssl.keyStoreType
にPKCS11
、javax.net.ssl.keyStore
NONE
と_javax.net.ssl.keyStoreProvider
を、構成ファイルで Sun PKCS#11 プロバイダーに指定された名前に変更します。
ここで私が間違っていることはありますか?任意のポインタや考えをいただければ幸いです。