Android Retrofit 进行 https 请求

申请证书

配置

  • 把 certificate.crt 文件放到 /res/raw 路径下

image-20210219103425018

  • 代码
...
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.KeyStore
import java.security.cert.CertificateFactory
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
...

/**
 * 加载 SSL 证书
 */
private fun initSSL(): List<Any> {
    val cf = CertificateFactory.getInstance("X.509")
    val inputStream = context.resources.openRawResource(R.raw.certificate)
    val ca = cf.generateCertificate(inputStream)
    val kStore = KeyStore.getInstance(KeyStore.getDefaultType())
    kStore.load(null, null)
    kStore.setCertificateEntry("ca", ca)
    val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
    tmf.init(kStore)
    val sslContext = SSLContext.getInstance("TLS")
    sslContext.init(null, tmf.trustManagers, null)
    return listOf(sslContext, tmf.trustManagers[0])
}

/**
 * 创建 [OkHttpClient]
 */
fun getClient(): OkHttpClient {
    val params = initSSL()
    return OkHttpClient.Builder()
        .sslSocketFactory(
            (params[0] as SSLContext).socketFactory,
            params[1] as X509TrustManager
        )
        .build()
}

/**
 * 创建服务
 */
fun <T> create(serviceClass: Class<T>, url: String): T {
    val builder = Retrofit.Builder()
        .baseUrl(url)
        .addConverterFactory(GsonConverterFactory.create())
        .client(getClient())

    return builder.build().create(serviceClass)
}