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