当前位置: 首页 > article >正文

OkHttp 的证书设置

在 Android 开发中,通过 OkHttp 自定义 SSLSocketFactory 和 X509TrustManager 可以有效增强 HTTPS 通信的安全性,防止中间人攻击(如抓包工具 Charles/Fiddler 的拦截)。以下是实现防抓包的关键技术方案:

一、Okhttp设置固定证书(推荐)

OkHttp 内置了证书固定功能,无需自定义 SSLSocketFactory,直接配置即可

         val certificatePinner = CertificatePinner.Builder()
                .add("example.com:443", "sha256/+o+LjQ5sWk3ABG4Gl7yZib6xTZ6F7OQ09qW7P9G+Z/Y=")
                .build()
         httpClient.certificatePinner(certificatePinner)

1、example.com: OpenSSL 要连接的 HTTPS 服务域名,你需要替换为实际的目标域名

2、443: 是 HTTPS 协议的默认端口号,若服务器 HTTPS 端口自己设置的,则需要修改

3、sha256/******: OpenSSL 获取到的证书

1、获取证书(服务器证书的公钥 SHA256 哈希值)

 在终端运行以下命令获取证书

openssl s_client -connect example.com:443 | openssl x509 -pubkey | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
  1. 连接到服务器openssl s_client -connect example.com:443 建立与目标服务器的 SSL 连接。注意⚠️:example.com:443 替换为你实际要连接的服务器地址和端口

  2. 提取证书openssl x509 -pubkey 从连接中提取证书的公钥部分。

  3. 转换格式openssl pkey -pubin -outform der 将公钥转换为 DER 格式(二进制)。

  4. 计算哈希openssl dgst -sha256 -binary 计算 DER 格式公钥的 SHA256 哈希。

  5. Base64 编码openssl enc -base64 将二进制哈希值转换为 Base64 字符串。

二、自定义 SSLSocketFactory + X509TrustManager

          如果需要更细粒度的控制(如仅信任特定证书)

1. 创建自定义 TrustManager
class CustomTrustManager : X509TrustManager {
    private val trustedCertificates by lazy { loadTrustedCertificates() }

    private fun loadTrustedCertificates(): List<X509Certificate> {
        // 从 assets 或 raw 目录加载证书(如 .crt 或 .pem 文件)
        val inputStream = context.assets.open("certificate.crt")
        val certificateFactory = CertificateFactory.getInstance("X.509")
        return certificateFactory.generateCertificate(inputStream) as X509Certificate
    }

    override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
        // 客户端证书验证
        throw CertificateException("Client certificates not supported!")
    }

    override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
        // 验证服务器证书链是否与预置证书匹配
        if (!trustedCertificates.contains(chain[0])) {
            throw CertificateException("Untrusted server certificate!")
        }
    }

    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}

    2. 创建自定义 SSLSocketFactory   

class CustomSSLSocketFactory(private val trustManager: X509TrustManager) : SSLSocketFactory() {
        private val sslContext by lazy {
            SSLContext.getInstance("TLS").apply {
                init(null, arrayOf(trustManager), SecureRandom())
            }
        }

        override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket {
            return sslContext.socketFactory.createSocket(s, host, port, autoClose)
        }

        // 其他重写方法(直接委托给 sslContext.socketFactory)
        override fun getDefaultCipherSuites(): Array<String> {
            sslContext.socketFactory.defaultCipherSuites
        }

        override fun getSupportedCipherSuites(): Array<String> {
            sslContext.socketFactory.supportedCipherSuites
        }

        override fun createSocket(host: String, port: Int): Socket {
            sslContext.socketFactory.createSocket(host, port)
        }

        override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket {
            sslContext.socketFactory.createSocket(host, port, localHost, localPort)
        }

        override fun createSocket(address: InetAddress, port: Int): Socket {
            sslContext.socketFactory.createSocket(address, port)
        }

        override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket {
            sslContext.socketFactory.createSocket(address, port, localAddress, localPort)
        }

    }
3. 配置 OkHttpClient
 val trustManager = CustomTrustManager()
    val sslSocketFactory = CustomSSLSocketFactory(trustManager)
    val okHttpClient =
        OkHttpClient.Builder()
            .sslSocketFactory(sslSocketFactory, trustManager)
            .hostnameVerifier { hostname, session ->
                HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)
            }.build()


http://www.kler.cn/a/586349.html

相关文章:

  • 蓝桥杯——路标设置
  • Celery - 入门(get-started)
  • 精准车型识别:视觉分析技术的力量
  • 海鲜水产行业wordpress外贸主题
  • Golang Channel 使用详解、注意事项与死锁分析
  • 软考教材重点内容 信息安全工程师 第19章 操作系统安全保护
  • Dify1.01版本vscode 本地环境搭建运行实践
  • AI+Python机器学习小项目教程(数据分类)
  • 算法基础 -- Brian Kernighan 算法初识
  • 基础知识《HTTP字段与状态码详细说明》
  • 【基于 SSE 协议与 EventSource 实现 AI 对话的流式交互】
  • Stable Diffusion API /sdapi/v1/txt2img的完整参数列表及其说明
  • leetcode hot 100(三)
  • python全栈-MySQL知识
  • MySQL:MySQL库和表的基本操作
  • SpringBoot实现一个Redis限流注解
  • Springboot项目修改端口
  • 深入理解Spring Boot:快速构建现代化的Java应用
  • 【调研】模型输出内容的json形式content怎样处理可以转换为json?
  • kafka生成者发送消息失败报错:RecordTooLargeException