一直在尝试使用PKCS#11令牌(智能卡)作为客户端的KeyStore(而不是TrustStore)来进行TLS连接的客户端身份验证。但是,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();
此外,这个实例化的KeyStore
用于使JSSE使用以下代码使用KeyManagerFactory
:
KeyManagerFactory kmf = javax.net.ssl.KeyManagerFactory.
getInstance( "SunX509", "SunJSSE" );
kmf.init( theKeyStore, <smart card pin> );
此KeyManagerFactory用于初始化SSLContext,然后用于实例化SSLSocket。
根据Oracle's JSSERefGuide for Java 6中的说明,这是我需要做的全部工作。虽然在以编程方式使用密钥库时不需要设置以下系统属性,但我也尝试添加系统属性:
javax.net.ssl.keyStoreType
至PKCS11
,javax.net.ssl.keyStore
至NONE
和javax.net.ssl.keyStoreProvider
到其配置文件中为Sun PKCS#11提供程序指定的名称。我在这里做错了什么想法?任何指针或想法都会非常感激。