2013-08-28 53 views
0

我正尝试通过SSL通过get/post Web服务调用来访问远程服务器。我使用阿帕奇的HttpClient以下方式:如何通过https解决Web服务回馈SSLHandshaking错误?

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(); 
} 

似乎在海报的工作,但我知道,证书位于浏览器,并处理所有的认证和证书的处理。我需要编写代码来获得此响应在别处使用。有任何想法吗?当代码被推送到服务器上时,这会是一个问题吗? (它是否需要不同的证书)。

编辑:这是添加的错误。

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

发生什么特定的SSLHandshakeException?请发布堆栈跟踪。另外,您要连接的主机使用哪种证书?它是由主要CA签署的,还是由其自己的CA签署的? – Syon

+0

CA自己选择。它尚未添加到密钥库中,但我试图绕过证书,因为这将用于测试目的。 – worm

回答

0

解决此问题的正确方法是将主机CA添加到您的JVM信任库(<jre directory>/lib/security/cacerts)。您可以通过在浏览器中浏览主机URL,查看该站点的证书(通常通过单击浏览器中URL旁边的锁定图标完成)并将CA导出到文件来获取CA证书。

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

当提示输入密码,默认为changeit

如果您不希望补充:一旦你的.crt文件,你可以使用keytool命令行工具将其导入到cacerts中将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只是绕过证书验证完全(我不推荐它),你可以创建一个TrustManager,它将信任任何证书like this

+0

非常感谢!我想我只是想绕过认证,然后检查认证是否有必要。它只会用于测试。 – worm