为什么我得到javax.net.ssl.SSLPeerUnverifiedException:peer只在生产中未经过身份验证?

时间:2012-04-05 19:32:07

标签: grails ssl https httpclient

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

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连接到US,我的请求开始失败并出现以下IOException:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

我试图弄清楚这里的失败点。

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

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

我不是一个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中添加我需要的东西而不是覆盖默认值以便每个人都满意?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

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

另一种方法是将默认Java商店中的所有内容添加到自定义商店中,并仍然使用java opt。无论你发现哪种情况更适合你的情况。