Android端关于HTTPS的认证---->可用

来源:互联网 发布:牡丹江管理局电视网络 编辑:程序博客网 时间:2024/06/03 14:51

1.关于HTTPS

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。

2.普通的HTTP post请求

public void requestPost(Map<String , String> params){    HttpURLConnection httpURLConnection = null;    String result = null;    try {        //合成参数        byte [] requestParams = generateParams(params);        URL url = new URL(requestUrl);        httpURLConnection = (HttpURLConnection) url.openConnection();        httpURLConnection.setConnectTimeout(60*1000);        httpURLConnection.setReadTimeout(60*1000);        httpURLConnection.setDoOutput(true);        httpURLConnection.setDoInput(true);        httpURLConnection.setUseCaches(false);        httpURLConnection.setRequestMethod("POST");        httpURLConnection.setInstanceFollowRedirects(true);        httpURLConnection.connect();        DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());        dos.write(requestParams);        dos.flush();        dos.close();        if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){            result = stream2string(httpURLConnection.getInputStream());        }else {            Log.e(TAG, "requestPost: 请求失败--->"+httpURLConnection.getResponseCode());        }        httpURLConnection.disconnect();    } catch (MalformedURLException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }}
当请求的接口地址变为HTTPS类型的话,会抛出如下异常

12-17 14:08:38.590 18126-18188/? W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:212)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.Connection.connect(Connection.java:1322)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:1410)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:131)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:484)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:465)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:371)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:476)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:25)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.binguokeji.sdk.library.SimpleNetHelper.post(***.java:232)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.binguokeji.sdk.library.Workflow$1.run(***.java:42)
12-17 14:08:38.590 18126-18188/? W/System.err:     at java.lang.Thread.run(Thread.java:818)
12-17 14:08:38.590 18126-18188/? W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:324)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:225)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:643)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
12-17 14:08:38.590 18126-18188/? W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:353)
12-17 14:08:38.590 18126-18188/? W/System.err:     ... 14 more
12-17 14:08:38.590 18126-18188/? W/System.err: Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err:     ... 20 more

有道上翻译的错误信息为----->没有找到认证路径的信任锚。   就是因为HTTPS请求有一层ssl加密协议,没有认证的话是不能随意访问的

3.为HTTPS请求设置信任证书

public void setCertificates(HttpsURLConnection httpsURLConnection , InputStream... certificates) {    try {        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());        keyStore.load(null);        int index = 0;        for (InputStream certificate : certificates) {            String certificateAlias = Integer.toString(index++);            keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));            try {                if (certificate != null)                    certificate.close();            } catch (IOException e) {            }        }        SSLContext sslContext = SSLContext.getInstance("TLS");        TrustManagerFactory trustManagerFactory =                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());        trustManagerFactory.init(keyStore);        sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());        httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());    } catch (Exception e) {        e.printStackTrace();    }}
在上边post请求的时候做一下判断

URL url = new URL(requestUrl);if (url.getProtocol().toUpperCase().equals("HTTPS")){    httpsURLConnection = (HttpsURLConnection) url.openConnection();    setCertificates(httpsURLConnection , new ByteArrayInputStream("信任证书的key".getBytes("UTF-8"));    httpURLConnection = httpsURLConnection;}httpURLConnection = (HttpURLConnection) url.openConnection();
这样就可以实现HTTPS类型地址的访问了

原创粉丝点击