使用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;
}
}