1

一直在尝试使用 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用于让KeyManagerFactoryJSSE 使用下面的代码:

KeyManagerFactory kmf = javax.net.ssl.KeyManagerFactory.
    getInstance( "SunX509", "SunJSSE" );

kmf.init( theKeyStore, <smart card pin> );

此 KeyManagerFactory 用于然后初始化 SSLContext,然后用于实例化 SSLSocket。

根据Oracle 的 JSSERefGuide for Java 6中的说明,这就是我需要做的全部工作。虽然在以编程方式使用密钥库时不需要设置以下系统属性,但我也尝试添加系统属性:

  • javax.net.ssl.keyStoreTypePKCS11,
  • javax.net.ssl.keyStoreNONE
  • javax.net.ssl.keyStoreProvider配置文件中为 Sun PKCS#11 提供程序指定的名称。

有什么想法我在这里做错了吗?任何指示或想法将不胜感激。

4

0 回答 0