【问题标题】:Unable to POST to https using Apache HTTP无法使用 Apache HTTP POST 到 https
【发布时间】:2017-05-07 08:07:17
【问题描述】:

我已经为此花费了数小时,但无法弄清楚原因。我什至使用了 bls.gov 网站上使用的部分代码示例。我不应该有任何问题,因为它是一个公共 API...请帮助!

public static void main(String[] args) throws ClientProtocolException, IOException {

     HttpHost proxy = new HttpHost("myproxy.com", 3128, "http");

    CloseableHttpClient httpClient = HttpClientBuilder.create().setProxy(proxy).build(); // Use
                                                                            // this
                                                                            // instead

    HttpPost request = new HttpPost("https://api.bls.gov/publicAPI/v1/timeseries/data/");
    StringEntity params = new StringEntity("{\"seriesid\":[\"LAUCN040010000000005\", \"LAUCN040010000000006\"]}");

    request.setEntity(params);

    request.setHeader("Accept", "application/json");
    request.setHeader("Content-type", "application/json");

    CloseableHttpResponse response = httpClient.execute(request);
    System.out.println("HERE");
    System.out.println(response.getStatusLine());
    response.close();

不断收到此错误:

  Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)

【问题讨论】:

    标签: java apache https


    【解决方案1】:

    您的 Java 信任库中必须有来自 https://api.bls.gov 的证书。

    在连接到该 URL 时,您可以从任何浏览器导入证书。

    您必须将证书添加到将用于您的程序的信任库中。 您可以使用 keytool 或 OpenSSL 来完成。

    有许多不同的方法来定义将使用哪个信任存储:

    1. 可以将证书添加到 JRE 级别的 Java 默认信任库中。 信任库是 JRE lib/security 文件夹中的 cacerts。 - 不推荐

    2. 可以将证书添加到启动时在 JVM 级别提供的信任存储中 -Djavax.net.ssl.trustStore 参数 - 不推荐(信任库密码必须在 -Djavax.net.ssl.trustStorePassword 中以开放文本形式提供)

    3. 从所需的信任存储文件(以及 HostnameVerifier)创建 SSLSocketFactory,然后将它们用于您的 https 连接。

    互联网上到处都有很多例子。只是尝试谷歌它。

    【讨论】:

      【解决方案2】:

      Java 对证书链非常挑剔。服务器是否也在传递中间证书?

      https://en.m.wikipedia.org/wiki/Intermediate_certificate_authority

      不是你。证书下发顺序不正确:https://www.ssllabs.com/ssltest/analyze.html?d=api.bls.gov

      【讨论】:

      • 请问这是什么意思?这是否意味着他们的证书存在问题,会阻止任何人获取数据?有办法解决吗?
      • 或多或少,是的。由于 java 在这里非常挑剔,因此默认配置的 Java 程序会遇到问题。主要问题是证书链中的错误顺序。此外,ssl 测试表明 SSL 配置存在重大问题、密码不安全等。如果您能够联系管理员,您可以要求他们解决此问题。
      • @gd000 可能是一种解决方法:stackoverflow.com/questions/21257455/…
      • 感谢您的回复。不幸的是,这没有用
      • @gd000 :-/ 你可以试试stackoverflow.com/a/2893932 选项 2。希望这对您有所帮助。但请参阅作者对漏洞的评论。
      猜你喜欢
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 2014-03-04
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      相关资源
      最近更新 更多