【问题标题】:handshake_failure when try to TLS handshake Client Authentication with SmartCard尝试使用智能卡进行 TLS 握手客户端身份验证时的握手失败
【发布时间】:2016-05-23 11:32:43
【问题描述】:

在 Apache 服务器中启用请求客户端证书并配置 SSL。全部适用于 Chrome 等浏览器。但是我们正在尝试直接创建客户端应用程序以使用 SmartCard 证书 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 App出现这个错误:

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

【问题讨论】:

    标签: java ssl tls1.2 handshake


    【解决方案1】:

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

    ¿您能否附上整个握手日志以详细查看每个步骤?

     -Djavax.net.debug=ssl
    

    Chrome 使用 Windows KeyStore,所以情况不一样。因为您的 java 代码使用的是 SunPKCS11 提供程序。

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

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

    【讨论】:

    • 谢谢@pedrofb,我用过Windows-MY,它会弹出并询问PIN2。但是出现这个错误Exception in thread "main" javax.net.ssl.SSLHandshakeException: Error signing certificate verify
    • 我猜如果弹出一个窗口,不是你,是司机。因此,您将无法通过代码输入 PIN2(请查看智能卡技术规范)。智能卡制造商这样做是为了防止 PIN2 落入坏人之手
    • 谢谢@pedrofb,异常呢? Exception in thread "main" javax.net.ssl.SSLHandshakeException: Error signing certificate verify
    • 这可能是 JDK 安全类和密钥库之间的兼容性问题。您可以使用 PCKS#11 和 Windows-MY 发布整个握手日志吗?你用的是哪个java版本?
    • 我们使用的是 java 8
    猜你喜欢
    • 2014-11-13
    • 2020-02-14
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    相关资源
    最近更新 更多