代码之家  ›  专栏  ›  技术社区  ›  peterh

强制发送客户端证书

  •  2
  • peterh  · 技术社区  · 8 年前

    我在用JavaSE Jersey 客户端连接到使用双向ssl的https资源。

    我的 SSLContext 看起来像这样:

    private SSLContext getSSLContext() {
        SslConfigurator sslConfig = SslConfigurator.newInstance()
            .keyStoreFile("src/main/certificates/testcert.p12")
            .keyPassword("mypassword");
    
       return sslConfig.createSSLContext();
    }
    

    问题是客户端证书从未发送。

    我得到错误“警告:找不到合适的证书-在没有客户端身份验证的情况下继续”并且我跟踪了客户端证书没有颁发给服务器的 证书请求 给客户的信息。我从测试中得知 cURL 不管服务器是否接受证书。端点是一个公共测试系统。

    我的问题是: 如何强制发送客户端证书? (即,我的JavaSE客户机应该忽略以下事实 testcert.p12 证书的颁发者不是服务器已表示将接受的颁发者列表)

    请不要告诉我有关禁用服务器证书检查或使用自签名证书的答案。服务器的证书很好。

    更新

    原来我的问题是另一个。通过设置系统属性进行调试 javax.net.debug=all 是的。在检查结果输出之后,即使在执行了上述操作之后,在我看来,密钥库也是空的。所以难怪“找不到合适的证书”。

    泽西有这个“聪明” SslConfigurator 帮助您设置 SSLContext公司 是的。也许对我来说太聪明了,因为我无法使用上面的代码。因此,我现在配置 SSLContext公司 如下所示:

        KeyStore ks = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream("src/main/certificates/testcert.p12");
        ks.load(fis, "mypassword".toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, "mypassword".toCharArray());
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(kmf.getKeyManagers(), null, null);
        // now use 'sc' in Jersey
    

    这对jersey的helper类不起作用,我完全赞同jersey为sslcontext创建helper类的想法,因为jsse对于这样一个简单的用例来说似乎过于复杂。好吧,好吧。

    1 回复  |  直到 8 年前
        1
  •  2
  •   user207421    8 年前

    不能。这将是TLS协议冲突,因此没有API支持它。各种TLS API仅在以下情况下发送客户端证书:

    1. 是被要求的,而且
    2. 可以找到符合 CertificateRequest 信息。

    您必须安排您的服务器信任您的客户端证书,方法是让它由ca签名,或者将其导出到服务器的受信任证书存储区,无论服务器采用何种形式。

    推荐文章