文档中心
OkHttp濡備綍璁剧疆HTTPS璇佷功锛熸墜鎶婃墜鏁欎綘鎼炲畾Android瀹夊叏閫氫俊
时间 : 2025-09-27 16:28:26浏览量 : 2

在移动应用开发中,网络安全是重中之重。如果你的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
override fun checkClientTrusted(chain: Array
override fun checkServerTrusted(chain: Array
override fun getAcceptedIssuers(): Array
})
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 详解