handshake_failure 尝试使用智能卡进行 TLS 握手客户端身份验证时
handshake_failure when try to TLS handshake Client Authentication with SmartCard
在 Apache 服务器中启用请求客户端证书并配置 SSL。所有都适用于 Chrome 等浏览器。但是我们正在尝试创建用于直接使用智能卡证书 PKCS11 进行身份验证的客户端应用程序(无需浏览器)。
这里是主要代码:
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);
在 Apache 服务器中启用请求客户端证书并配置 SSL。所有都适用于 Chrome 等浏览器。但是我们正在尝试创建用于直接使用智能卡证书 PKCS11 进行身份验证的客户端应用程序(无需浏览器)。
这里是主要代码:
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);