okhttp配置自签名https证书

作者: 蓝不蓝编程 | 来源:发表于2019-05-24 17:30 被阅读3次

    背景

    有些时候,为了做内部测试,服务器上得配置自签名证书,这样安卓客户端需要通过自签名证书去访问.

    解决方案

    1. 增加工具类HttpsUtil
    class HttpsUtil {
        class SSLParams {
            lateinit var sSLSocketFactory: SSLSocketFactory
            lateinit var trustManager: X509TrustManager
        }
    
        private class UnSafeTrustManager : X509TrustManager {
            @SuppressLint("TrustAllX509TrustManager")
            @Throws(CertificateException::class)
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
            }
    
            @SuppressLint("TrustAllX509TrustManager")
            @Throws(CertificateException::class)
            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
            }
    
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }
    
    
        private class MyTrustManager @Throws(NoSuchAlgorithmException::class, KeyStoreException::class)
        constructor(private val localTrustManager: X509TrustManager) : X509TrustManager {
            private val defaultTrustManager: X509TrustManager?
    
            init {
                val var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
                var4.init(null as KeyStore?)
                defaultTrustManager = chooseTrustManager(var4.trustManagers)
            }
    
    
            @SuppressLint("TrustAllX509TrustManager")
            @Throws(CertificateException::class)
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
    
            }
    
            @Throws(CertificateException::class)
            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
                try {
                    defaultTrustManager!!.checkServerTrusted(chain, authType)
                } catch (ce: CertificateException) {
                    localTrustManager.checkServerTrusted(chain, authType)
                }
            }
    
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }
    
        companion object {
    
            fun getSslSocketFactory(certificates: Array<InputStream>, bksFile: InputStream?, password: String?): SSLParams {
                val sslParams = SSLParams()
                try {
                    val trustManagers = prepareTrustManager(*certificates)
                    val keyManagers = prepareKeyManager(bksFile, password)
                    val sslContext = SSLContext.getInstance("TLS")
                    var trustManager: X509TrustManager = UnSafeTrustManager()
    
                    trustManagers?.let { arrayOfTrustManagers ->
                        val x509TrustManager = chooseTrustManager(arrayOfTrustManagers)
                        x509TrustManager?.let { trustManager = MyTrustManager(it) }
                    }
    
                    sslContext.init(keyManagers, arrayOf<TrustManager>(trustManager), null)
                    sslParams.sSLSocketFactory = sslContext.socketFactory
                    sslParams.trustManager = trustManager
                    return sslParams
                } catch (e: Exception) {
                    throw AssertionError(e)
                }
            }
    
            private fun prepareTrustManager(vararg certificates: InputStream): Array<TrustManager>? {
                if (certificates.isEmpty()) return null
                try {
                    val certificateFactory = CertificateFactory.getInstance("X.509")
                    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
                    keyStore.load(null)
                    for ((index, certificate) in certificates.withIndex()) {
                        val certificateAlias = Integer.toString(index)
                        keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate))
                        try {
                            certificate.close()
                        } catch (e: IOException) {
                        }
                    }
    
                    val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
                    trustManagerFactory.init(keyStore)
    
                    return trustManagerFactory.trustManagers
                } catch (e: Exception) {
                    e.printStackTrace()
                }
    
                return null
            }
    
            private fun prepareKeyManager(bksFile: InputStream?, password: String?): Array<KeyManager>? {
                try {
                    if (bksFile == null || password == null) return null
    
                    val clientKeyStore = KeyStore.getInstance("BKS")
                    clientKeyStore.load(bksFile, password.toCharArray())
                    val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
                    keyManagerFactory.init(clientKeyStore, password.toCharArray())
                    return keyManagerFactory.keyManagers
    
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
                return null
            }
    
            private fun chooseTrustManager(trustManagers: Array<TrustManager>): X509TrustManager? {
                for (trustManager in trustManagers) {
                    if (trustManager is X509TrustManager) {
                        return trustManager
                    }
                }
                return null
            }
        }
    }
    
    1. 生成okHttpClient时设置sslSocketFactory
    fun provideOkHttpClient(): OkHttpClient {
            val sslParams = HttpsUtil.getSslSocketFactory(arrayOf(App.context.resources.openRawResource(R.raw.https_keystore)), null, null)
            return OkHttpClient.Builder()
                    .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                    .build()
        }
    

    附录

    https工具类来自鸿洋

    安卓开发技术分享: https://www.jianshu.com/p/442339952f26
    点击关注专辑,查看最新技术分享
    更多技术总结好文,请关注:「程序园中猿」

    相关文章

      网友评论

        本文标题:okhttp配置自签名https证书

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