如何在SSL / TLS期间使用智能卡作为KeyStore进行客户端身份验证?

时间:2013-08-14 23:36:39

标签: authentication ssl client pkcs#11

一直在尝试使用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.keyStoreTypePKCS11
  • javax.net.ssl.keyStoreNONE
  • javax.net.ssl.keyStoreProvider到其配置文件中为Sun PKCS#11提供程序指定的名称。

我在这里做错了什么想法?任何指针或想法都会非常感激。

0 个答案:

没有答案