Android Https请求 信任自签名的证书

2017-12-08  本文已影响351人  Lost_Robot

1.何为Https

2.请求Https和Http的区别

3.Okhttp 3框架的使用说明

4.OkHttp3 网络框架如何请求Https

OKHTTP访问https
okhttp访问https也是很简单的,如果是访问CA机构颁发证书的网站,比如https://github.com/ ,默认情况下是可以信任的。但是有些自签名的证书访问就不行了,一般都是有两种办法,一种是默认信任所有的证书,客户端不做任何检查,这种简单快捷但是不安全;还有一种就是让android客户端信任自签名的证书,比如12306网站的证书。

1.Android 客户端默认信任所有的证书
//默认信任所有的证书(实践成功):
fun getUnsafeOkHttpClient(): OkHttpClient {
    try {
        // Create a trust manager that does not validate certificate chains
        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {

            override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {}

            override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {}

            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return emptyArray<X509Certificate>()
            }

        })

        // Install the all-trusting trust manager
        val sslContext = SSLContext.getInstance("SSL")
        sslContext.init(null, trustAllCerts, java.security.SecureRandom())
        // Create an ssl socket factory with our all-trusting manager
        val sslSocketFactory = sslContext.getSocketFactory()

        val builder = OkHttpClient.Builder()
        builder.sslSocketFactory(sslSocketFactory)
        builder.hostnameVerifier { hostname, session ->
            true

        }

        val okHttpClient = builder.build()
        return okHttpClient
    } catch (e: Exception) {
        throw RuntimeException(e)
    }

}

//使用Get请求https,忽略证书
 val IRISURL = "https://123.125.219.144:8443/mobileConnect/MobileConnect/authFIDOPayWebVersion2.action?sid=1986606&mobile=MOBILE&pipe=2&reqt=REQTIME&productname=84mp"
 val irisurl = IRISURL.replace("MOBILE", mUserName?.text.toString(), false)
                    .replace("REQTIME", System.currentTimeMillis().toString(), false)
 val request: Request = Request.Builder().url(irisurl).method("GET", null).build()
getUnsafeOkHttpClient().newCall(request).enqueue(object : Callback {

                override fun onFailure(call: Call, e: IOException) {

                    mHandle.sendEmptyMessage(ERROR_IRIS_Auth)

                }

                override fun onResponse(call: Call, response: Response) {

                    // Log.e(TAG, "body>>>>${response?.body()?.string()}")
                    val responseStr = response?.body()?.string()
                    if (response?.code() == 200) {
                        val responseJson = JSONObject(responseStr)
                        val irisResult = Gson().fromJson(responseJson?.get("results").toString(), IRISResult::class.java)

                        if (irisResult.result.equals("00")) {
                            //登录成功
                            mHandle.sendEmptyMessage(IRIS_Auth_SUCCESS)

                        } else {

                            mHandle.sendEmptyMessage(ERROR_IRIS_Auth)

                        }
                    } else {
                        val bundle: Bundle = Bundle()
                        bundle.putString(ERRORMESSAGE, response?.message())

                        val msg = Message()
                        msg.what = GET_DATA_FAIL
                        msg.arg1 = response?.code() ?: ERROR_UnKnow
                        msg.data = bundle

                        mHandle.sendMessage(msg)
                    }


                }

            })

2.android客户端信任自签名证书(未实践):

我们把12306的证书放到assets下面,这样就可以读取成功了,okhttp的配置还是一样的。

public SSLContext getSLLContext(){
        SSLContext sslContext = null;
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream cerInputStream = getApplicationContext().getAssets().open("12306.cer");
            Certificate ca = cf.generateCertificate(cerInputStream);
 
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
 
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
            TrustManager[] trustManagers = tmf.getTrustManagers();
 
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustManagers, null);
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return  sslContext;
    }

上一篇 下一篇

猜你喜欢

热点阅读