ssl新闻资讯

文档中心

OkHttp濡備綍璁剧疆HTTPS璇佷功锛熸墜鎶婃墜鏁欎綘鎼炲畾Android瀹夊叏閫氫俊

时间 : 2025-09-27 16:28:26浏览量 : 2

2OkHttp濡備綍璁剧疆HTTPS璇佷功锛熸墜鎶婃墜鏁欎綘鎼炲畾Android瀹夊叏閫氫俊

在移动应用开发中,网络安全是重中之重。如果你的App通过HTTPS与服务器通信,但没正确配置证书,可能会导致中间人攻击(比如黑客在公共WiFi窃取数据)。今天我们就用大白话+实际案例,聊聊OkHttp如何设置HTTPS证书,涵盖自签名证书、CA机构证书等常见场景。

一、为什么需要手动设置HTTPS证书?

假设你的App访问 `https://your-api.com`,OkHttp默认会信任系统内置的CA机构(如DigiCert、Let's Encrypt)颁发的证书。但以下情况需要手动处理:

1. 自签名证书:比如公司内网测试环境用的证书。

2. 非权威CA颁发的证书:某些小众CA可能不被系统信任。

3. 证书固定(Pinning):防止黑客用伪造的CA证书攻击(比如2011年DigiNotar事件)。

二、基础操作:信任指定证书

场景1:你的服务器用的是自签名证书

```kotlin

// 步骤1:把服务器的.crt或.pem证书文件放在assets文件夹

// 步骤2:代码加载证书并创建TrustManager

val certificateFactory = CertificateFactory.getInstance("X.509")

val inputStream = context.assets.open("your_cert.crt")

val certificate = certificateFactory.generateCertificate(inputStream)

// 创建一个KeyStore存放我们的证书

val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())

keyStore.load(null, null)

keyStore.setCertificateEntry("server", certificate)

// 用KeyStore创建TrustManager

val trustManagerFactory = TrustManagerFactory.getInstance(

TrustManagerFactory.getDefaultAlgorithm()

)

trustManagerFactory.init(keyStore)

// 配置到OkHttpClient

val sslSocketFactory = SSLContext.getInstance("TLS").apply {

init(null, trustManagerFactory.trustManagers, null)

}.socketFactory

val okHttpClient = OkHttpClient.Builder()

.sslSocketFactory(sslSocketFactory, trustManagerFactory.trustManagers[0] as X509TrustManager)

.build()

```

风险提示:这种方式完全信任指定证书,适合测试环境。生产环境建议结合域名校验。

三、进阶操作:证书固定(Certificate Pinning)

场景2:防止中间人攻击(比如恶意CA签发假证书)

.certificatePinner(

CertificatePinner.Builder()

.add("your-api.com", "sha256/AAAAAAAAAAAAAAAA=") // 替换为你的公钥哈希

.build()

)

如何获取公钥哈希?

1. 用命令提取:

```bash

openssl s_client -connect your-api.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

```

2. 或者代码运行时捕获异常,OkHttp会返回预期的哈希值。

四、混合模式:仅调试时信任自签名证书

开发阶段经常需要连接测试环境,但又不希望影响生产代码:

fun buildOkHttpClient(isDebug: Boolean): OkHttpClient {

val builder = OkHttpClient.Builder()

if (isDebug) {

// 调试模式下信任所有证书(危险!仅用于开发)

builder.sslSocketFactory(

getUnsafeSSLSocketFactory(),

getUnsafeTrustManager()

)

builder.hostnameVerifier { _, _ -> true }

} else {

// 生产环境使用严格校验

builder.certificatePinner(...)

}

return builder.build()

}

private fun getUnsafeSSLSocketFactory(): SSLSocketFactory {

val trustAllCerts = arrayOf(object : X509TrustManager {

override fun checkClientTrusted(chain: Array?, authType: String?) {}

override fun checkServerTrusted(chain: Array?, authType: String?) {}

override fun getAcceptedIssuers(): Array = arrayOf()

})

return SSLContext.getInstance("SSL").apply {

init(null, trustAllCerts, SecureRandom())

}.socketFactory

五、常见问题排查清单

1. 错误:`SSLHandshakeException`

- ?检查设备时间是否正确(过期的系统时间会导致证书失效)。

- ?确认证书是否过期(`openssl x509 -in cert.crt -text`查看有效期)。

2. 错误:`HostnameVerifier`不匹配

- ?如果是IP地址访问,需要关闭主机名校验(仅限测试!)。

3. Android低版本兼容性问题

- ?Android 7.0以下需要自己配置TLS协议版本:

```kotlin

builder.connectionSpecs(listOf(ConnectionSpec.MODERN_TLS))

```

六、最佳实践表

| 场景 | 推荐方案 | 安全性等级 |

||-|-|

| 生产环境 | Certificate Pinning + CA校验 | ????? |

| 企业内部测试 | 手动加载自签名证书 | ??? |

| Debug模式 | (临时)信任所有证书 | ? |

记住一个原则:网络请求的安全性=正确的加密+正确的验证。OkHttp只是工具,关键看你怎么用它!

TAG:okhttp 设置https证书,okhttp+,okhttp配置https,okhttp入门,okhttp 详解