【问题标题】:SSLConnectionSocketFactory always returns 400(2 way ssl client cert) Certificates were not receivedSSLConnectionSocketFactory 始终返回 400(2 路 ssl 客户端证书)未收到证书
【发布时间】:2019-02-27 18:43:31
【问题描述】:

我有一个ssl连接(2次握手),我无法理解为什么下面的代码过程400(openJdk 11,服务器提供的p12文件和密码,服务器提供的cer文件),

我已经通过以下命令从 cer 文件创建了 jks 文件:

keytool -importcert -file example-api.cer -keystore example-api.jks

代码

    File keyFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-client-api1.p12")).getFile());
    File trustFile = new File(Objects.requireNonNull(exampleController.class.getClassLoader().
            getResource("example-api.jks")).getFile());
    KeyStore keyStore  = KeyStore.getInstance("PKCS12");
    try(FileInputStream inStream = new FileInputStream(keyFile)) {
        keyStore.load(inStream, "password".toCharArray());
    }
    SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustFile, "password".toCharArray() ,new TrustAllStrategy()).
                            loadKeyMaterial(keyStore , "password".toCharArray()).build();
    HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
    SSLConnectionSocketFactory socketFactory =
            new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLHostnameVerifier(hostnameVerifier)
            .setSSLSocketFactory(socketFactory)
            .useSystemProperties()
            .build();
    HttpGet httpget = new HttpGet("https://example-api/link?token=@Secret_Token@");

    System.out.println("executing request" + httpget.getRequestLine());

    return  httpclient.execute(httpget);

上面的代码总是返回 400(没有发送所需的 SSL 证书)。

但以下 curl 有效(在 IOS 上):

curl https://example-api/link?token=@secret_token@ --cacert ./example-api-ca.crt --cert ./example-client-api1.p12:password

任何帮助将不胜感激

【问题讨论】:

  • 可能是useSystemProperties() 使用了系统的属性而不是您的特定配置。尝试删除它
  • @pedrofb 嗨,不走运,它没有帮助,我想补充一点,我们实际上从服务器获得了一个 .crt 文件,并将其转换为 Base 64 .cer 文件(在 Windows 中)然后使用了cer文件,这会导致问题吗?我必须使用crt吗?
  • 需要将服务器证书或CA根证书添加到信任库。这不是问题。您收到由服务器管理的错误,因此 SSL 通道已建立,但未提供客户端证书。此问题通常是由包含客户端证书的密钥库配置错误引起的。还要检查文件路径
  • (1) 您的 curl 构建使用什么中间件?检查curl -V(大写vee)(2)使用sysprop javax.net.debug=ssl 运行和/或使用wireshark 或类似工具获取线路跟踪,并检查服务器请求的CA 与证书链中的CA(在P12 for后者)(3)大多数人对 DER 和 PEM 使用后缀 .crt(这不是 完全 base64)和 .cer 对于 DER,但 MS 两者都使用,而 java @987654329 @ 两者都接受,加上TrustAll 无论如何都会忽略您的信任库
  • @pedrofb,我运行了以下命令:keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias test -filegravityx-api-ca.cer 警告:使用 -cacerts 选项访问cacerts keystore 证书已添加到密钥库,但问题仍然存在。

标签: java ssl certificate jks sslcontext


【解决方案1】:

好吧,在经历了一些令人沮丧的日子之后: 我不知道原因,但问题在于 URL 的主机名中的连字符('-'),删除连字符修复了问题,不知道为什么,但无论如何发布它,也许有人可以解释这种现象。 示例(使用上面的代码):

example-api -> not working
example.api -> Works OK

【讨论】:

    猜你喜欢
    • 2014-06-25
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2015-08-07
    • 2010-10-16
    • 2017-04-28
    相关资源
    最近更新 更多