【问题标题】:force-sending client certificate强制发送客户端证书
【发布时间】:2018-12-08 00:16:16
【问题描述】:

我正在使用 Java SE Jersey 客户端连接到使用双向 SSL 的 HTTPS 资源。

我的SSLContext 看起来像这样:

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

   return sslConfig.createSSLContext();
}

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

我收到错误“警告:未找到合适的证书 - 在没有客户端身份验证的情况下继续”,我已经跟踪了客户端证书未颁发给服务器 中列出的证书颁发机构之一这一事实的原因CertificateRequest 消息给客户端。我从cURL 的测试中知道服务器无论如何都会接受证书。端点是一个公共测试系统。

我的问题:如何强制发送我的客户端证书?(即我的 Java SE 客户端应该忽略 testcert.p12 证书的颁发者不是服务器拥有的颁发者列表的事实表示会接受)

请不要向我指出有关禁用服务器证书检查或有关使用自签名证书的答案。服务器的证书就好了。

更新

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

Jersey 有这个“聪明的”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 的助手类没有的地方。我完全赞同 Jersey 为 SSLContext 提供帮助类的想法,因为对于这样一个简单的用例,在这里 JSSE 似乎过于复杂。不错不错。

【问题讨论】:

标签: java ssl jersey ssl-certificate


【解决方案1】:

你不能。这将违反 TLS 协议,因此没有 API 支持它。各种 TLS API 只会在以下情况下发送客户端证书:

  1. 已请求,并且
  2. 可以找到符合CertificateRequest 消息中指定内容的客户端证书。

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

【讨论】:

  • 谢谢。完全有道理。
猜你喜欢
  • 2018-09-05
  • 2011-05-04
  • 2012-03-27
  • 2013-06-06
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多