我试图通过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
答案 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 this的TrustManager
。