Android(Jetpack Compose+Ktor)与Go(Gin)安全连接配置问询
客户端证书认证配置方案(Ktor Android + Go Gin)
一、Ktor Android客户端配置(使用本地DER证书)
加载raw目录中的DER格式证书
从Android资源中读取证书文件,转换为X509Certificate对象:val certificateFactory = CertificateFactory.getInstance("X.509") val certInputStream = context.resources.openRawResource(R.raw.client_cert) val clientCert = certificateFactory.generateCertificate(certInputStream) as X509Certificate certInputStream.close()构建SSL上下文
将证书存入KeyStore,生成信任管理器并创建SSLContext:val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply { load(null, null) setCertificateEntry("clientCert", clientCert) } val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply { init(keyStore) } val sslContext = SSLContext.getInstance("TLS").apply { init(null, trustManagerFactory.trustManagers, SecureRandom()) }配置Ktor HttpClient
在HttpClient的engine配置中指定SSL上下文,确保请求使用HTTPS:val httpClient = HttpClient(OkHttp) { engine { sslContext = sslContext // 若服务端用自签名证书(上线建议替换为权威CA证书),可临时禁用主机名验证(上线必须开启严格验证) // hostnameVerifier = HostnameVerifier { _, _ -> true } } defaultRequest { url("https://your-server-domain.com") } }
二、Go Gin服务端配置(仅接受合法客户端证书的请求)
准备CA证书(信任客户端证书的根证书)
若客户端证书是自签名的,直接用该证书作为CA证书;若为CA签发,使用对应CA根证书,保存为ca.crt文件。加载CA证书池
import ( "crypto/tls" "crypto/x509" "io/ioutil" "log" "fmt" "github.com/gin-gonic/gin" "net/http" ) func loadCAPool() *x509.CertPool { caCert, err := ioutil.ReadFile("ca.crt") if err != nil { log.Fatalf("读取CA证书失败: %v", err) } caPool := x509.NewCertPool() if !caPool.AppendCertsFromPEM(caCert) { log.Fatal("添加CA证书到证书池失败") } return caPool }配置Gin的HTTPS服务器
设置TLS配置,强制要求客户端提供并验证证书有效性:func main() { r := gin.Default() // 仅允许合法客户端证书访问的示例接口 r.GET("/api/secure", func(c *gin.Context) { if peerCerts := c.Request.TLS.PeerCertificates; len(peerCerts) > 0 { cert := peerCerts[0] log.Printf("收到合法请求,客户端证书CN: %s", cert.Subject.CommonName) } c.JSON(200, gin.H{"status": "success", "message": "客户端证书验证通过"}) }) tlsConfig := &tls.Config{ // 强制要求客户端提供证书并验证有效性 ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: loadCAPool(), // 自定义证书校验逻辑(可选):比如检查证书CN、指纹等 VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { cert, err := x509.ParseCertificate(rawCerts[0]) if err != nil { return err } // 示例:校验证书CN是否符合预期 if cert.Subject.CommonName != "your-android-app-client" { return fmt.Errorf("客户端证书CN不合法") } return nil }, } server := &http.Server{ Addr: ":443", Handler: r, TLSConfig: tlsConfig, } // 启动HTTPS服务,传入服务端证书和密钥文件路径 log.Fatal(server.ListenAndServeTLS("server.crt", "server.key")) }
注意事项
- 上线环境请使用权威CA签发的证书,避免自签名证书带来的安全风险和兼容性问题。
- Android端上线时必须启用严格的主机名验证,禁止随意禁用。
- Go服务端可根据业务需求,在
VerifyPeerCertificate中添加更严格的校验规则,比如证书指纹匹配、有效期检查等。
内容的提问来源于stack exchange,提问作者tomerpacific
相关产品推荐
相关产品推荐

