1. 程式人生 > 其它 >Java HttpClient如何帶證書發起請求

Java HttpClient如何帶證書發起請求

技術標籤:JavajavaHttpClientSSL證書

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
	at sun.security.ssl.Alerts.getSSLException
(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639) at sun.security.
ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037) at sun.security.ssl.Handshaker.process_record(Handshaker.java:965) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064) at sun.security.ssl.SSLSocketImpl.
performInitialHandshake(SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)

如果我們在開發中使用HttpClient遇到了上面的錯誤,說明對方的介面需要特定的證書才能請求,那麼如何在HttpClient請求中加入證書呢?
請看下面的程式碼


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;

/**
 * @author niudali
 * @date 2021/2/3 11:16
 * @desc
 */

public class HttpUtil {

    private static SSLContext sslContext = null;
    private static HttpClient httpClient = new DefaultHttpClient();
    private static String siteUrl = "";


    private static String KEY_STORE_CLIENT_PATH = "";
    private static String KEY_STORE_TRUST_PATH = "";
    private static String KEY_STORE_PASSWORD = "";


    /**
     * @param _siteUrl
     * @param p12Path .p12檔案地址
     * @param trustPath .truststore檔案地址
     * @param password 金鑰密碼
     */
    public static void init(String _siteUrl, String p12Path, String trustPath, String password) {

        try {
            siteUrl = _siteUrl;
            KEY_STORE_CLIENT_PATH = p12Path;
            KEY_STORE_TRUST_PATH = trustPath;
            KEY_STORE_PASSWORD = password;
            //設定環境變數
            System.setProperty("javax.net.ssl.keyStore", KEY_STORE_CLIENT_PATH);
            System.setProperty("javax.net.ssl.keyStorePassword", KEY_STORE_PASSWORD);
            System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
            System.setProperty("javax.net.ssl.trustStore", KEY_STORE_TRUST_PATH);
            System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_PASSWORD);
            System.setProperty("javax.net.ssl.trustStoreType", "jks");
            KeyStore kstore = KeyStore.getInstance("PKCS12");
            kstore.load(new FileInputStream(KEY_STORE_CLIENT_PATH), KEY_STORE_PASSWORD.toCharArray());
            KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
            keyFactory.init(kstore, KEY_STORE_PASSWORD.toCharArray());
            KeyStore tstore = KeyStore.getInstance("jks");
            tstore.load(new FileInputStream(KEY_STORE_TRUST_PATH), KEY_STORE_PASSWORD.toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
            tmf.init(tstore);
            TrustManager[] tm = tmf.getTrustManagers();
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(keyFactory.getKeyManagers(), tm, (SecureRandom) null);
        } catch (Exception e) {
            e.printStackTrace();

        }

    }
    public static String httpPost(String url, String jsonParam) {
        try {
            httpClient = new DefaultHttpClient();
            SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
            Scheme sch = new Scheme("https", 443, socketFactory);
            httpClient.getConnectionManager().getSchemeRegistry().register(sch);
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json");
            httpPost.addHeader("charset", "UTF-8");
            httpPost.setEntity(new StringEntity(jsonParam.toString(), "UTF-8"));
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity);
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

}