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,但它并没有帮助。

+1

请发布您的HTTP客户端安装程序的完整代码,包括SSLContext的初始化和设置。另外,您使用的是哪个版本的HttpClient? 3? 4? –

我重构我的旧代码来处理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);` 
+0

正如我在我的问题中提到的,我试图忽略。它不起作用。 – Igor

+0

然后尝试将证书作为可信证书添加到您的Java商店 – arodriguezdonaire

+0

问题是,当我使用邮递员发出请求时,它会成功添加任何证书或其他任何内容。我不明白为什么在我的代码它不 – Igor