OkHttp 的证书设置

embedded/2025/3/18 2:38:26/

在 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.ppmy.cn/embedded/173468.html

相关文章

JVM 详解:Java 虚拟机的核心机制

目录 引言&#xff1a;为什么 JVM 是 Java 生态的基石&#xff1f; 一、什么是 JVM&#xff1f; 1.1 JVM 的核心作用 二、JVM 的架构 2.1 类加载器&#xff08;Class Loader&#xff09; 2.2 运行时数据区&#xff08;Runtime Data Areas&#xff09; 2.3 执行引擎&#…

《Python深度学习》第四讲:计算机视觉中的深度学习

计算机视觉是深度学习中最酷的应用之一&#xff0c;它让计算机能够像人类一样“看”和理解图像。想象一下&#xff0c;计算机可以自动识别照片中的物体、人脸&#xff0c;甚至可以读懂交通标志。这一切听起来是不是很神奇&#xff1f;其实&#xff0c;这一切都离不开深度学习中…

kafka 中的 rebalance

Kafka 的 Rebalance&#xff08;重平衡&#xff09;机制本质上是一个协调过程&#xff0c;用于在消费者组内动态分配分区&#xff0c;以保证消费任务均匀分布。Rebalance 主要由 Kafka Consumer Group 协议&#xff08;Group Membership Protocol&#xff09;驱动&#xff0c;涉…

Linux 文件与目录操作指令

以下是 Linux 文件与目录操作指令的详细整理&#xff0c;涵盖 基本操作、权限管理、查找统计、压缩解压 等场景&#xff0c;包含常用选项与示例&#xff1a; 一、目录导航与查看 1. pwd&#xff1a;显示当前目录的绝对路径 <BASH> pwd # 输出&#xff1a;/hom…

OpenWebUI项目调研对比

开源地址&#xff1a;https://github.com/open-webui/open-webui 官方文档&#xff1a;https://docs.openwebui.com/ OpenWebUI(以前称为Ollama WebUl)是一款面向大型语言模型(LLMs)的用户友好型Web界面&#xff0c;支持Ollama和兼容OpenAl的API运行。 通过一个直观的界面&a…

【STM32】USART串口协议串口外设-学习笔记

串口协议 通信接口 通信的目的&#xff1a;将一个设备的数据传送到另一个设备&#xff0c;扩展硬件系统。比如STM32芯片内部集成了很多功能模块&#xff0c;像定时器计数、PWM输出、AD采集等等。这些都是芯片内部的电路&#xff0c;这些电路的配置寄存器&#xff0c;数据寄存…

SSL/TLS 1.2过程:Client端如何验证服务端证书?

快速回顾非对称加密和对称加密 首先快速说一下非对称加密和对称加密。非对称加密&#xff0c;就是有一个公钥和私钥(成对存在)。 公钥对一段文本A加密得到文本B&#xff0c;只有对应的私钥能对B解密得到A。 私钥对一段文本C加密得到文本D&#xff0c;只有对应的公钥能对D解密得…

unity生命周期

unity的生命周期 都是有序的1. 实例化与初始化阶段Awake()OnEnable() 2. 开始与更新阶段Start()FixedUpdate()Update()LateUpdate() 3. 渲染阶段OnPreCull()OnBecameVisible() 和 OnBecameInvisible()OnWillRenderObject()OnRenderObject()OnPostRender() 4. 销毁阶段OnDisable…