You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

本地环境下服务器与Android客户端HTTPS通信配置问题排查

解决Android模拟器访问本地HTTPS服务器的SSL握手错误

别慌,这个SSLHandshakeException本质就是Android系统不信任你自己生成的自签名证书——哪怕你加了CertificatePinner,证书钉住的前提是证书本身被系统信任,不然验证链还是断的。而且你是本地练习项目,完全可以搞定,给你两个靠谱的方案:

方案一:把自签名证书导入Android模拟器(更贴近正式环境逻辑)

这个方法是让模拟器真正信任你的服务器证书,步骤很简单:

  1. 从p12导出单独的证书文件
    keytool命令把你的p12证书里的公钥导出成Android能识别的格式:

    keytool -exportcert -alias sampleName -keystore resources/keystore/sampleName.p12 -storetype PKCS12 -storepass samplePassword -file server_cert.cer
    

    执行完会生成一个server_cert.cer文件。

  2. 把证书传到模拟器里
    用adb命令把证书推到模拟器的存储:

    adb push server_cert.cer /sdcard/
    
  3. 在模拟器里手动安装证书
    打开模拟器的设置 → 安全 → 加密与凭据 → 从存储安装,找到刚才推的server_cert.cer,随便起个名字(比如MyLocalServer),然后选择VPN和应用用途完成安装。

    安装完重启下你的Android应用,再发请求应该就能正常握手了。

方案二:配置OkHttp跳过证书验证(仅本地练习用!正式环境绝对禁用)

如果不想手动装证书图省事,就给OkHttp加个自定义的信任管理器,让它接受所有证书(仅限练习,正式环境这么做等于裸奔)。修改你的OkHttpClient代码:

// 注意:仅用于本地练习项目,正式生产环境严禁使用!
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
    override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
    override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
    override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray()
})

// 创建自定义SSL上下文
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustAllCerts, SecureRandom())
val sslSocketFactory = sslContext.socketFactory

// 构建OkHttpClient
val httpClient = OkHttpClient.Builder()
    .certificatePinner(
        CertificatePinner.Builder()
            // 注意:这里的host不要带https://,只写IP+端口即可
            .add("10.0.2.2:8080", "sha256/lVIcG+gpmlabsq1bW5RbvB+kqVSHKdOFyoxjo9+SLEs=")
            .build()
    )
    .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
    .hostnameVerifier { _, _ -> true } // 忽略主机名验证,因为是本地IP
    .build()

额外注意点

  • 你之前的CertificatePinner里写的是"https://10.0.2.2:8080",这个格式不对!应该去掉https://,只保留"10.0.2.2:8080",不然钉住的主机和实际请求的主机不匹配,也会导致验证失败。
  • 再确认下服务器端的application.properties配置:路径、密码、别名必须和你生成p12证书时完全一致,比如server.ssl.key-store=classpath:keystore/sampleName.p12要确保这个文件确实在resources/keystore目录下。

本地环境完全可以实现这个功能,放心折腾就行,毕竟是练习项目,怎么方便怎么来~

内容的提问来源于stack exchange,提问作者David Holkup

火山引擎 最新活动