You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android(Jetpack Compose+Ktor)与Go(Gin)安全连接配置问询

客户端证书认证配置方案(Ktor Android + Go Gin)

一、Ktor Android客户端配置(使用本地DER证书)

  1. 加载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()
    
  2. 构建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())
    }
    
  3. 配置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服务端配置(仅接受合法客户端证书的请求)

  1. 准备CA证书(信任客户端证书的根证书)
    若客户端证书是自签名的,直接用该证书作为CA证书;若为CA签发,使用对应CA根证书,保存为ca.crt文件。

  2. 加载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
    }
    
  3. 配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:08:11