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证书

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

  • 踩坑记

    1、android自签名证书Glide加载不出图片 关于https中自签名证书的介绍以及OkHttp中解决自签名证...

  • OkHttp配置https使用自签名证书问题

    近期需要在OkHttp框架上加入自签名的证书配置https,参考了这个兄弟的文章并配置好客户端证书后,报了java...

  • Okhttp 访问多个自签名证书 HTTPS 地址解决方案

    首先参考Okhttp 访问自签名证书 HTTPS 地址解决方案上面这篇博客,解决了访问自签名证书的问题。但是有时候...

  • Okhttp3 Https请求配置自签名证书

    有关Https请求的原理本篇帖子不做过多赘述,今天要做的就是带领大家配置Https请求中自签名证书的问题 先贴一段...

  • nginx配置自签名https

    nginx配置https是需要CA颁发证书的,为了测试方便,我们可以使用自签名证书1.如何生成自签名证书1.1:我...

  • 2019-03-05

    ubuntu 配置自签名数字证书开启https服务 1. 生成证书:自签名数字证书的生成跟MacOS一样,可以参见...

  • 当Fresco/Picasso遇到https(2)----访问自

    上文讲述的加载https的时候,不使用证书安全校验。本文讲述-------使用OkHttp请求自签名的https网...

  • 2018-03-16

    HTTPS 单向双向认证 自签证书自签名的证书 CA证书 并且上传到github上面✅ 屏幕支持横屏的配置✅视频...

  • Android HTTPS之自签名证书认证(二)

    使用okhttp框架 双向认证 在上一篇博客中《Android HTTPS之自签名证书认证(一)单向认证》,我们主...

网友评论

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

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