【问题标题】:Why do I get javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated only in production?为什么我会得到 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated only in production?
【发布时间】:2012-04-05 19:32:06
【问题描述】:

我有一个 grails 1.3.7 应用程序,它使用 apache HttpClient 对第三方进行 https api 调用。我点击的第三方 URL 具有有效证书。我像这样创建并执行我的请求:

HttpClient client = new DefaultHttpClient()

List<BasicNameValuePair> queryParams = new ArrayList<BasicNameValuePair>()
queryParams.add(new BasicNameValuePair("a_parameter", "a_parameter_value"))

URI uri = URIUtils.createURI("https", "third.party.address", 443, "/some/url/for/us", URLEncodedUtils.format(queryParams, "UTF-8"), null)
HttpGet httpGet = new HttpGet(uri)

try {
    log.debug "Sending request to ${uri}"
    return client.execute(httpGet)
} catch(HttpException e) {
    log.error "HttpException during location lookup request: ${e}"
    return
} catch(IOException e) {
    log.error "IOException during location lookup request: ${e}"
    return
}

当我在开发模式下运行我的项目时,这可以正常工作。我还可以直接从 curl 和我的浏览器调用相同的 URL,没有错误。但是,一旦我的项目被构建到一个 war 文件中并放在一个定义了证书/密钥库的 tomcat 实例上,以便客户端可以使用 https 连接到我们,我的请求开始失败,并出现以下 IOException:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

我试图找出这里的失败点。

为什么从 curl 或我的开发模式发出 https 请求与从配置了 https 的 tomcat 实例发出 https 请求不同?

tomcat 实例不可公开访问,但当我从浏览器连接到它时没有证书问题(chrome 表示证书很好,详细的 curl 请求也是如此)。

无论如何,我都不是 https/ssl 专家,因此我正在寻求帮助,解释什么是错误的、为什么是错误的,以及如何解决它。我可以提供任何其他需要的信息。

---更新--- 我按照下面的建议启用了javax.net.debug,输出包含以下错误:

java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be\
 non-empty

我的谷歌搜索让我认为这个问题是因为我在启动 tomcat 时使用了以下 java opt:

-Djavax.net.ssl.trustStore=/path/to/tomcat/conf/myStore.jks

如果是这样,我怎样才能在 myStore.jks 中添加我需要的东西,而不是覆盖默认值,让每个人都开心?

【问题讨论】:

  • 您可以尝试使用 javax.net.debug 属性打开 SSL 调试 - 请参阅 herongyang.com/JDK/…
  • 我已经用启用它提供的少量信息更新了帖子。

标签: grails ssl https httpclient


【解决方案1】:

对我来说最终的解决方案是我们用我们自己的 java opt 覆盖了默认的 java 信任存储。这导致第三方发送的证书看起来无效,因为我们的 myStore.jks 中没有任何默认根证书。

通过将我们的自签名证书添加到默认的 java 证书 (/lib/security/cacerts) 并删除 java opt,一切都很好。

另一种方法是将默认 java 存储中的所有内容添加到您的自定义存储中,并且仍然使用 java opt。对于您的情况,无论哪种方式更易于维护。

【讨论】:

    【解决方案2】:

    我已经多次看到这个错误。我使用以下实用程序从使用 SSL 的站点获取证书。去这里抓住InstallCert。编译并运行此实用程序。您可以将此实用程序生成的文件用作密钥库。

    【讨论】:

      猜你喜欢
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 2014-03-21
      • 2023-01-12
      • 2018-07-01
      • 2022-01-11
      相关资源
      最近更新 更多