如何通过https绕过Web服务回复SSLHandshaking错误?

时间:2013-08-28 18:24:26

标签: java web-services apache authentication ssl-certificate

我试图通过SSL上的get / post Web服务调用来访问远程服务器。我正在以下列方式使用aptt HttpClient:

HttpClient client = new HttpClient();
client.getHostConfiguration().setProxy("my_host", 443);
Credentials defaultcreds = new UsernamePasswordCredentials("dev", "password");
client.getState().setCredentials(new AuthScope("my_host", 443, AuthScope.ANY_REALM),  defaultcreds);

// Create a method instance.
GetMethod method = new GetMethod(url);

// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
    new DefaultHttpMethodRetryHandler(3, false));

try {
    // Execute the method.
    int statusCode = client.executeMethod(method);

if (statusCode != HttpStatus.SC_OK) {
    System.err.println("Method failed: " + method.getStatusLine());
}

    // Read the response body.
    byte[] responseBody = method.getResponseBody();

// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
System.out.println(new String(responseBody));

} catch (HttpException e) {
    System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
    System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
    // Release the connection.
    method.releaseConnection();
}

它似乎在POSTER中工作,但我知道证书位于浏览器中,并且处理所有身份验证和证书处理。我需要编写代码才能将此响应用于其他地方。有任何想法吗?当代码被推送到服务器上时,这会成为一个问题吗? (是否需要不同的证书)。

编辑:这是添加的错误。

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

1 个答案:

答案 0 :(得分:0)

解决此问题的正确方法是将主机CA添加到JVM信任库(<jre directory>/lib/security/cacerts)。您可以通过浏览浏览器中的主机URL,查看站点的证书(通常通过单击浏览器中URL旁边的锁定图标来完成)以及将CA导出到文件来获取CA证书。获得.crt文件后,可以使用keytool命令行工具将其导入cacerts:

keytool -keystore cacerts -importcert -alias someName -file yourCertFilename

提示输入密码时,默认值为changeit

如果您不想将CA添加到默认信任库,则可以使用SSLSocketFactory创建自己的信任库文件,以便在创建时将其传递给HttpClient

keytool -keystore myTrustStore.jks -importcert -alias someName -file yourCertFilename

在提示时输入您选择的密码。

KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("myTrustStore.jks"), trustStorePassword);
SSLSocketFactory sf = new SSLSocketFactory(trustStore);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);

(上面的代码不在我的脑海中,尚未经过测试,但它应该会给你一个想法。)

或者,如果您希望HTTPClient完全绕过证书验证(我不推荐),您可以创建一个信任任何证书like thisTrustManager