问题描述:

I'm trying to issue a post request in the next manner:

  • I use Apache's HttpClient 3.1
  • I use encoding "application/x-www-form-urlencoded"
  • The URL I use starts with https

this is the code I try to run:

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) {}

}

Upon executing executeMethod I catch:

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

I tried to disable certificate validation but it did not help.

网友答案:

If you want to ignore the certificate all together then take a look at the answer here Ignore self-signed ssl cert using Jersey Client

Although this will make your app vulnerable to man-in-the-middle attacks.

You can instead of this try adding the certificate to your java store as a trusted cert. This site may be helpful. http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/

Here's another answer showing how to add a cert to your store. Java SSL connect, add server cert to keystore programatically

The key is

KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert);
ks.setEntry("someAlias", newEntry, null);`
网友答案:

I refactored my old code to handle https. Now it works and looks like this:

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;
}
相关阅读:
Top