美文网首页
Android Https请求 信任自签名的证书

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

作者: Lost_Robot | 来源:发表于2017-12-08 14:21 被阅读351次

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

    相关文章

      网友评论

          本文标题:Android Https请求 信任自签名的证书

          本文链接:https://www.haomeiwen.com/subject/qdzjixtx.html