尝试进行TLS握手时发生handshake_failure使用智能卡进行客户端身份验证

问题描述:

在Apache服务器和SSL中配置了请求客户端证书。所有与Chrome浏览器一起使用。但我们正在尝试创建客户端应用程序,以便直接使用智能卡证书PKCS11进行身份验证(无需浏览器)。尝试进行TLS握手时发生handshake_failure使用智能卡进行客户端身份验证

下面是主要的代码:当握手步骤运行时发生

 String configName = "d:/config.txt"; 

     SunPKCS11 sunpkcs11 = new SunPKCS11(configName); 
     Security.addProvider(sunpkcs11); 
     KeyStore keyStore = null; 

     keyStore = KeyStore.getInstance("PKCS11",sunpkcs11); 
     keyStore.load(null, pin.toCharArray()); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     kmf.init(keyStore, pin.toCharArray()); 


     SSLContext ctx = SSLContext.getInstance("TLS"); 
     ctx.init(kmf.getKeyManagers(), null, null); 
     SSLContext.setDefault(ctx); 
     final SSLSocketFactory factory = ctx.getSocketFactory(); 
     final SSLSocket socket = (SSLSocket) factory.createSocket("xx.xx.xx.xx", 443); 

     socket.startHandshake(); 

     PrintWriter out = new PrintWriter(socket.getOutputStream()); 

     String fileName = "/Login"; 
     out.print("GET " + fileName + " HTTP/1.0\r\n"); 
     out.print("\r\n"); 
     out.flush(); 

     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     String line; 
     while ((line = in.readLine()) != null) 
      System.out.println(line); 

错误。

堆栈跟踪异常:

main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failu 

在Apache日志,我们得到这样的:

Certificate Verification: Error (20): unable to get local issuer certificate 

而Java应用程序出现此错误:

Warning: no suitable certificate found - continuing without client authentication 
*** Certificate chain 
<Empty> 

似乎SSLContext中无法正确使用PKCS#11提供程序访问智能卡,然后服务器关闭连接,因为客户端哈没有发送签名。

可以附上整个握手日志以详细了解每一步吗?

-Djavax.net.debug=ssl 

Chrome使用Windows KeyStore,因此它不是相同的情况。因为你的java代码正在使用SunPKCS11提供程序。

您是否试过通过Windows KeyStore使用智能卡?

KeyStore keystore = KeyStore.getInstance("Windows-MY"); 
keystore.load(null, null); 
+0

谢谢@pedrofb,我用'Windows-MY'它弹出并询问PIN2。但是,这个错误发生'线程中的异常'主要“javax.net.ssl.SSLHandshakeException:签名证书验证错误' –

+0

我们如何通过代码传递pin2请求? –

+0

我想如果一个窗口弹出来,它不是你,是司机。因此,您将无法通过代码输入PIN2(请查看智能卡技术规格)。智能卡制造商这样做是为了防止PIN2落入他人手中 – pedrofb