天天看點

HttpsURLConnection使用HttpsURLConnection通路https資源(自簽名)

使用HttpsURLConnection通路https資源(自簽名)

原創

passengers

工作日志

2017/07/07 16:44

閱讀數 3.5K

https(安全超文本傳輸協定)與http(超文本傳輸協定)相比,多了一層SSL認證,需要我們提供特定網點的證書才能通路 如果我們純粹的用HttpsURLConnection去通路,則會報異常(使用不同的架構會導緻所報的異常不同)

解決辦法: 一、設定HttpsURLConnection,讓它信任所有證書(即跳過驗證步驟) 二、為HttpsURLConnection添加一個所信任的證書 代碼: 方法一:信任所有證書 public class GetUndoVerifyHttpsRequest {

final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {

    public boolean verify(String hostname, SSLSession session) {
        return true;
    }	//将所有驗證的結果都設為true
};

public static String getStart(String urlString) throws Exception {
    HttpURLConnection httpURLConnection;
    HttpsURLConnection httpsURLConnection;

    URL url = new URL(urlString);
    trustAllHosts();
    httpsURLConnection = (HttpsURLConnection) url.openConnection();

    if (url.getProtocol().toLowerCase().equals("https")) {
        httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY);
        httpURLConnection = httpsURLConnection;
    } else {	//判斷是https請求還是http請求
        httpURLConnection = (HttpURLConnection) url.openConnection();
    }
    httpURLConnection.setRequestMethod("GET");
    httpURLConnection.setReadTimeout(5000);

    if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        InputStream inputStream = httpURLConnection.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) != -1) {
            byteArrayOutputStream.write(bytes, 0, len);
        }
        String values = new String(byteArrayOutputStream.toByteArray());
        inputStream.close();
        byteArrayOutputStream.close();

        return values;
    }
    return null;
}

/**
 * 不檢查任何證書
 */
private static void trustAllHosts() {
    final String TAG = "trustAllHosts";
    // 建立信任管理器
    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            Log.i(TAG, "checkClientTrusted");
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            Log.i(TAG, "checkServerTrusted");
        }
    }};

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
           

} 方法二:添加證書驗證 public class GetVerifyHttpsRequest {

private static TrustManagerFactory trustManagerFactory;

public static String getStart(String urlString, Context context) throws Exception {

    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    InputStream inputStreamCrt = context.getAssets().open("load-der.crt");//将你所導出的證書放入Assets檔案中,在這裡引用
    Certificate certificate = certificateFactory.generateCertificate(inputStreamCrt);

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", certificate);

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
    trustManagerFactory.init(keyStore);

    getRequest(urlString);
    return tmfAlgorithm;
}

public static String getRequest(String urlString) throws Exception {
    HttpsURLConnection httpsURLConnection;

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    URL url = new URL(urlString);

    httpsURLConnection = (HttpsURLConnection) url.openConnection();
    httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
    httpsURLConnection.setRequestMethod("GET");
    httpsURLConnection.setReadTimeout(5000);

    if (httpsURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        InputStream inputStream = httpsURLConnection.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) != -1) {
            byteArrayOutputStream.write(bytes, 0, len);
        }
        String values = new String(byteArrayOutputStream.toByteArray());
        inputStream.close();
        byteArrayOutputStream.close();

        return values;
    }
    return null;
}
           

}

(附)普通連接配接:
           

public class GetNormalVerifyHttpRequest { public static String getStart(String urlString) throws Exception { HttpsURLConnection httpsURLConnection;

URL url = new URL(urlString);//擷取位址,将其轉換成URL類
    httpsURLConnection = (HttpsURLConnection) url.openConnection();//通過位址拿到連接配接
    httpsURLConnection.setRequestMethod("GET");//設定請求方式(GET請求還是POST)
    httpsURLConnection.setReadTimeout(5000);//設定連接配接逾時時間

    if (httpsURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//如果傳回碼等于200,建立一個讀入流來讀取網絡上的資料
        InputStream inputStream = httpsURLConnection.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) != -1) {
            byteArrayOutputStream.write(bytes, 0, len);
        }//寫入資料
        String values = new String(byteArrayOutputStream.toByteArray());//将所讀到的資料通過String的構造方法放入values中,并關流傳回
        inputStream.close();
        byteArrayOutputStream.close();

        return values;
    }
    return null;
}
           

}

繼續閱讀