HttpClient的HTTPS POST请求失败
我试图发出在接下来的方式后要求:HttpClient的HTTPS POST请求失败
- 我使用Apache的HttpClient3.1
- 我使用的编码“应用程序/ x-WWW-窗体-urlencoded”
- 我使用的URL以https
开始,这是我尝试运行代码:
public static String httpsPost(String url, String body, String mediaType, String encoding) {
disableCertificateValidation();
HttpClient client = new HttpClient();
StringRequestEntity requestEntity = new StringRequestEntity(body, mediaType, encoding);
PostMethod method = new PostMethod(url);
method.setRequestEntity(requestEntity);
client.executeMethod(method);
}
public static void disableCertificateValidation() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (Exception e) {}
}
在执行executeMethod
我赶上:
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
我试图disable certificate validation,但它并没有帮助。
我重构我的旧代码来处理HTTPS。现在它的工作原理如下:
public static String httpsPost(String url, String body, String mediaType, String encoding) {
SSLContext ctx;
ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
URL serverUrl = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) serverUrl.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.connect();
OutputStreamWriter post = new OutputStreamWriter(con.getOutputStream());
post.write(body);
post.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
String content = "";
while ((inputLine = in.readLine()) != null) {
content += inputLine;
}
post.close();
in.close();
return content;
}
如果你想忽略证书一起再看看这里Ignore self-signed ssl cert using Jersey Client
答案虽然这会令您的应用程序容易受到中间人中间人攻击。
您可以尝试将证书作为可信证书添加到您的Java商店。此网站可能会有所帮助。 http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/
下面是显示如何将证书添加到商店的另一个答案。 Java SSL connect, add server cert to keystore programatically
的关键是
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert);
ks.setEntry("someAlias", newEntry, null);`
正如我在我的问题中提到的,我试图忽略。它不起作用。 – Igor
然后尝试将证书作为可信证书添加到您的Java商店 – arodriguezdonaire
问题是,当我使用邮递员发出请求时,它会成功添加任何证书或其他任何内容。我不明白为什么在我的代码它不 – Igor
请发布您的HTTP客户端安装程序的完整代码,包括SSLContext的初始化和设置。另外,您使用的是哪个版本的HttpClient? 3? 4? –