mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
5772 字
16 分钟
ssl pinning以及计算机网络知识笔记

SSL Pinning原理以及网络知识笔记#

一、前言#

有时候,你会发现某个app或许抓不了包,很有可能就是pinning在作祟。

这里我整理了相关知识以及原理,希望对你有所帮助。

二、发起请求后的流程#

概括就是:访问www.91.com ->DNS进行解析拿到ip地址 -> 进行tcp三次握手建立通道 -> TLS握手(取决于是否用了https) -> 加密传入http包和响应

flowchart TD A[输入域名 / App 发起请求] --> B[DNS:域名解析为 IP] B --> C[路由 / 代理 / TCP 连接] C --> D[TLS 握手] D --> E[验证服务器证书链、有效期、主机名] E --> F{是否启用 Pinning?} F -- 是 --> G[比较证书或公钥指纹] F -- 否 --> H[继续] G --> H H --> I{是否启用 mTLS?} I -- 是 --> J[客户端发送证书并证明持有私钥] I -- 否 --> K[建立加密通道] J --> L[服务器验证客户端证书] L --> K K --> M[通过 TLS 传输 HTTP 请求/响应]

有四点值得关注:

  1. CA / 证书链验证:我能否信任对方提供的证书?
  2. Hostname Verification:证书是否是签给我正在访问的主机名?
  3. Certificate/Public-Key Pinning:除了系统信任链外,我是否只接受预先指定的证书或公钥?
  4. mTLS 客户端认证:服务器是否要求客户端也出示证书,并证明自己持有对应私钥?

三、名词解析#

1.DNS是什么#

DNS(Domain Name System,域名系统)负责把类似 api.example.com 的域名解析成 IP 地址。它类似互联网的”电话簿”,但不负责加密 HTTP 内容,也不负责证明服务器身份。

sequenceDiagram participant App as App / 系统解析器 participant DNS as DNS 解析器 participant Server as 目标服务器 App->>DNS: 查询 api.example.com DNS-->>App: 返回 IP 地址(可能有多个) App->>Server: 对 IP 建立网络连接

几个要点:

  • DNS 通常发生在 TCP/TLS 握手之前。
  • DNS 返回一个 IP,不等于这个 IP 上的服务就可信。
  • HTTPS 的服务器证书仍需要验证证书链、有效期、用途和主机名。
  • DNS 出错可能让客户端连到错误地址,但正确的 HTTPS 主机名验证通常会阻止冒充服务器。
  • DNS 查询本身是否加密,取决于使用的是传统 DNS、DoT(DNS over TLS)、DoH(DNS over HTTPS)等方式。
  • 直接访问 IP 时,证书主机名校验可能失败,因为证书通常签给域名而不是该 IP。

这里出现了几个名词,Dot以及Doh,来看看他们出现的原因吧。

传统 DNS 通常通过 UDP 53 端口查询,也可以使用 TCP 53。它默认不加密,因此同一网络路径上的观察者可能看到你查询的域名,也可能篡改响应。


DOT#

DoT = DNS over TLS,也就是“通过 TLS 传输 DNS”。

它保留 DNS 查询的内容和语义,但在 DNS 数据外面增加 TLS 加密保护。

特点:

  • 通常使用 TCP 853 端口。
  • DNS 查询和响应在传输过程中受到 TLS 加密保护。
  • 网络路径上的旁观者通常无法直接读取 DNS 查询内容。
  • 网络观察者仍可能看到你连接了哪个 DNS 服务器,以及连接的时间、流量大小等元数据。

DOH#

DoH = DNS over HTTPS,也就是“通过 HTTPS 传输 DNS”。

它同样保护 DNS 查询,但不是使用专门的 DoT 协议端口,而是把 DNS 查询放进 HTTPS 请求中发送。

特点:

  • 常见情况下使用 HTTPS 的 443 端口。
  • DNS 查询被封装在 HTTPS 请求中。
  • 因为和普通 HTTPS 共用常见的 Web 传输方式,单靠端口号通常无法判断某个连接是不是 DoH。
  • 和 DoT 一样,连接本身的元数据仍可能暴露;加密也不会阻止 DNS 服务提供商看到它处理的查询。

2.Https和tls#

HTTPS 可以理解为 HTTP 运行在 TLS 安全通道之上。TLS(Transport Layer Security)负责建立安全连接,并在握手后加密保护应用数据。

flowchart LR A[HTTP 请求/响应] --> B[TLS 记录层:加密与完整性保护] B --> C[TCP 或 QUIC 传输] C --> D[网络]

TLS 主要提供:

  • 机密性:旁观者不能直接读出加密后的 HTTP 内容。
  • 完整性:数据被修改时通常会被检测到。
  • 服务器身份认证:客户端通过证书链等机制验证服务器。
  • 可选的客户端身份认证:mTLS 中服务器也验证客户端证书。

TLS 不会自动让应用逻辑安全,也不保证服务器业务行为可信。若 App 主动忽略证书错误,或把秘密写进日志,TLS 本身无法解决这些问题。

3.TLS握手流程#

sequenceDiagram participant C as 客户端(Android App) participant S as 服务器 C->>S: ClientHello(支持的版本、算法、随机数等) S-->>C: ServerHello(协商参数) S-->>C: 服务器证书链及握手证明 Note over C: 校验证书链、有效期、用途和主机名 C->>S: 客户端完成握手证明 Note over C,S: 双方派生会话密钥 C->>S: 加密的 HTTP 请求 S-->>C: 加密的 HTTP 响应

4.啥是证书、ca、证书链#

比如X.509证书,有下面这些内容

  • Subject:证书主体,例如 CN=api.example.com。
  • Issuer:签发者名称。
  • Subject Public Key:主体公钥。
  • Validity:有效起止时间。
  • Subject Alternative Name(SAN):证书适用的 DNS 名称或 IP。
  • Key Usage / Extended Key Usage:允许的用途,例如服务器认证、客户端认证。
  • Serial Number、签名算法、签名值等。
Subject: CN=api.example.com
Issuer: CN=Example Intermediate CA
Serial Number: 01:A2:B3:C4
Validity:
Not Before: 2026-01-01
Not After: 2027-01-01
Subject Public Key:
Algorithm: RSA
Key Size: 2048 bits
Subject Alternative Name:
DNS:api.example.com
Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm:
SHA256withRSA
Signature:
[一段数字签名数据]

总结一下:证书里藏了重要的公钥和签名算法,他可以是任意一方颁发并用于身份自证以及通信的工具。

CA(Certificate Authority,证书颁发机构)负责签发和管理证书。客户端通过本地信任锚(通常是根CA 证书)验证一条证书链。

所以CA做了啥事?

服务器生成密钥对(私钥揣兜里,公钥公开)->向 CA 提交申请,证明对域名或身份具有相应控制权->
CA 对证书内容生成数字签名->客户端验证签名链、有效期、用途和主机名

总结就是套娃,CA相当于中介(草泥马的黑心中介!),他做的事情也和服务端一样。用自己的私钥对服务端给的证书进行签名,而客户端天生是信任CA的,手里有着CA的公钥,所以能够拿到服务端的证书。

flowchart TD R[根 CA:本地信任锚] --> I[中间 CA 证书] I --> L[服务器叶子证书:api.example.com] L --> P[客户端验证:签名链、有效期、用途、主机名]

CA常见来源(浏览器也是一个套路)包括:

  1. Android 系统预置的受信任 CA。
  2. 用户手动安装的 CA(现代 Android 的应用是否信任用户 CA,取决于系统版本和应用 Network Security Config 等配置)。
  3. App 自己加载的 CA 或证书。
  4. 自定义 TrustManager / TrustStore。

5.TLS里的几个Manager#

一句话概括:KeyManager 负责“证明自己”,TrustManager 负责“信任别人”,HostnameVerifier 负责“核对名字”。

维度KeyManager(密钥管理器)TrustManager(信任管理器)HostnameVerifier(主机名验证器)
核心职责管理本地身份凭证,向对端”证明自己”管理信任材料,决定”是否信任对方”核对证书中的身份标识与实际连接目标是否匹配
处理的数据本地私钥 + 证书链(KeyStore 密钥库)受信任的 CA 根证书(TrustStore 信任库)对端证书中的 SAN/CN + 实际连接的主机名
回答的问题”我该用哪套证书向对方证明我是谁?""对方出示的证书链是否可信?""这张(已可信的)证书是不是发给这个主机的?“
在 Java 中的接口javax.net.ssl.KeyManagerjavax.net.ssl.TrustManagerjavax.net.ssl.HostnameVerifier
典型实现/工厂KeyManagerFactory + KeyStoreTrustManagerFactory + TrustStore(默认 cacerts)HttpsURLConnection 默认实现,或自定义
何时被调用握手需要出示本地证书时(服务器端、或 mTLS 客户端)收到对端证书链、需要验证时TrustManager 验证通过之后,再校验主机名
客户端场景是否必需通常不需要(除非 mTLS)必需必需(HTTPS 场景)
服务器端场景是否必需必需(出示服务器证书)可选(仅 mTLS 验证客户端时)不适用(服务器一般不校验客户端主机名)
校验失败后果无法出示证书,握手失败证书链不可信,握手失败连接被拒绝(防中间人/证书错配)
其他语言的对应机制Go:tls.Config.Certificates;OpenSSL:SSL_CTX_use_certificate / use_PrivateKeyGo:RootCAs、VerifyPeerCertificate;OpenSSL:SSL_CTX_load_verify_locations、verify 回调Go:tls.Config.ServerName 隐式校验;OpenSSL:X509_VERIFY_PARAM_set1_host
一句话记忆证明自己信任别人核对名字

6.什么是SSL pinning#

“SSL Pinning”是常见叫法,更准确地说通常是证书固定或公钥固定(Certificate Pinning / Public-Key Pinning)。

常规 HTTPS 验证大致问:

这张证书能否沿着有效的证书链追溯到我信任的 CA?它是否有效、用途正确、主机名匹配?

Pinning 则额外问:

这个证书或公钥,是否正是应用预先指定、允许接受的那一个?

即使代理工具生成的证书由手机信任的 Charles CA 签发,App 的 Pinning 仍可能拒绝它,因为该证书的公钥或证书指纹与 App 预期值不同。

所以这里是抓包工具被检测的关键。

Charles / mitmproxy 等 HTTPS解密代理会在客户端与代理之间呈现一张代理生成的证书,并在代理与服务器之间另建连接。即使Android 信任 Charles 根CA,代理证书的公钥也通常与服务器原始公钥不同,因此 Pinning 会失败。

7.常见的pinning#

  • 证书指纹固定:比较整个证书的哈希值。
  • 公钥 / SPKI 固定:提取证书中的 Subject Public Key Info,再做哈希比较。
  • 自定义固定逻辑:应用自己解析证书、比较摘要、维护状态或在失败时拒绝请求。

本项目案例中看到的代码会对公钥 SPKI 数据做 SHA-256,再编码成 Base64 与预期 pin 比较。这属于公钥固定思路。

实际 App 可能使用 OkHttp 的CertificatePinner,也可能自己实现这套逻辑。

具体流程如下

flowchart TD A[收到服务器证书] --> B[常规 TLS 证书链验证] B -->|失败| X[拒绝连接] B -->|成功| C[主机名验证] C -->|失败| X C -->|成功| D[Pinning 比较证书或 SPKI 哈希] D -->|不匹配| X D -->|匹配| E[允许继续]

8.双向TLS是什么?#

普通 HTTPS的典型情况是客户端验证服务器;服务器通常通过账号密码、Token、会话 Cookie等方式识别用户。

mTLS 在 TLS握手中增加客户端证书认证:服务器要求客户端提供证书,并验证客户端是否持有对应私钥。

sequenceDiagram participant C as Android 客户端 participant S as mTLS 服务器 C->>S: ClientHello S-->>C: ServerHello S-->>C: Certificate(服务器证书链) S-->>C: ServerKeyExchange(如需要) S-->>C: CertificateRequest(请求客户端证书) S-->>C: ServerHelloDone Note over C: TrustManager 验证服务器证书链 Note over C: HostnameVerifier 校验服务器主机名 C->>S: Certificate(KeyManager 选择客户端证书,可能为空) C->>S: ClientKeyExchange C->>S: CertificateVerify(仅当发送了非空证书) C->>S: ChangeCipherSpec + Finished Note over S: 用其 TrustManager 验证客户端证书 S-->>C: ChangeCipherSpec + Finished C->>S: 加密应用数据(客户端 → 服务器) S-->>C: 加密应用数据(服务器 → 客户端)

客户端证书常见如client.12

PKCS#12(常见扩展名 .p12 / .pfx)通常是一个容器,可能包含:

  • 客户端证书;
  • 与证书匹配的私钥;
  • 一条或多条中间 CA 证书;
  • 保护容器内容的密码。

容器密码用于保护文件中的秘密,不是客户端证书,也不是 CA 证书。

9.抓包工具是如何工作的#

抓包常被混为两类:网络包捕获,以及 HTTPS 中间人代理(MITM Proxy)。它们不是一回事。

普通网络抓包是Wireshark、tcpdump 等工具捕获网络接口上的数据包。对明文HTTP,可能直接看到请求和响应;对 HTTPS,通常只能看到IP、端口、连接元数据以及部分握手信息,应用内容是加密的。

https解密代理是Charles、mitmproxy、Burp Suite 等在代理模式下,通常会拆成两条独立的 TLS连接:

sequenceDiagram participant App as Android App participant Proxy as Charles participant Server as 目标服务器 App->>Proxy: TLS 连接 A(App 验证代理出示的证书) Proxy->>Server: TLS 连接 B(代理验证服务器证书) App->>Proxy: 加密 HTTP 请求 A Note over Proxy: 解密后显示 HTTP 内容 Proxy->>Server: 在连接 B 中重新加密并转发请求 Server-->>Proxy: 加密 HTTP 响应 B Proxy-->>App: 在连接 A 中重新加密响应

可以看到,抓包工具做了一个中间人,与客户端,服务端都进行了TLS链接。

mTLS 代理面对的是两段连接:

  1. App → Charles:App 验证 Charles 的证书。
  2. Charles → 服务器:服务器可能要求 Charles 提供客户端证书。

所以这里显而易见的,客户端需要信任代理抓包软件的CA,这个需要手动放到手机的信任证书里。

但要弄清几点:安装 CA 并不代表: - App 一定信任用户安装的 CA; - Pinning一定会通过; - 所有 App 流量都会自动进入代理; - mTLS的服务器端客户端证书要求会自动满足。

10.代理和vpn#

都讲抓包了,这两个也记个笔记。

区别如下

  • 代理的定义是应用或系统把指定的网络请求交给代理服务器,再由代理转发到目标服务器。例如 Charles、HTTP 代理、SOCKS5 代理。
  • VPN是在设备与 VPN 服务端之间建立加密隧道,再按路由规则把流量送进隧道。例如 WireGuard、OpenVPN、IPsec VPN。
  • 出口ip是目标网站看到的网络连接来源 IP。它可能是家庭宽带、移动网络、数据中心或 VPN 服务商的出口。

概括一下

  • 代理:你请中间人帮你转交某类信件。
  • VPN:你修了一条通往远端网络的加密隧道。
  • 出口 IP:对方在信件上看到的寄件地址。

VPN 服务本身也可能通过代理、NAT 或其他网络设备转发流量;它们不是完全互斥的技术。

代理的几大份分类:

方式A:显示代理

比如 Android 的 Wi-Fi 代理设置为:

代理服务器:192.168.1.10
代理端口:8888
当支持系统代理的应用访问网站时,会根据代理配置把请求发给 192.168.1.10:8888,由代理再连接目标服务器。

方式 B:透明转发

透明代理或网关可以通过网络路由、防火墙规则等手段,把符合规则的流量转发到中间设备。应用未必需要显式配置代理。

但“透明转发”不等于自动解密 HTTPS:没有客户端与中间设备之间合适的 TLS 处理和信任配置,代理通常仍然看不到 HTTPS 的明文内容。

方式 C:VPN 隧道

VPN 常通过操作系统的虚拟网络接口接收流量,再把它封装进隧道发送给远端 VPN 服务器。

App
↓
系统网络栈
↓
VPN 虚拟网卡
↓
加密隧道
↓
VPN 服务器
↓
互联网目标服务器

在 Android 上,VPN 应用通常使用 VpnService 创建虚拟接口,并通过路由规则决定哪些流量进入隧道。

VPN 是否承载全部流量,要看它的路由配置;分流 VPN 可能只接管某些应用或某些目标网段。

代理的分类#

代理可以从不同角度分类,不是只有一种分类方法。

  1. 按代理协议分类
类型工作方式常见用途
HTTP 代理转发 HTTP 请求;HTTPS 通常通过 CONNECT 建立隧道Web 访问、调试抓包
HTTPS 代理通常指客户端到代理这段连接本身使用 TLS 加密的代理保护客户端与代理之间的通信
SOCKS4 / SOCKS5在更底层转发连接,不局限于 HTTP 请求格式通用 TCP 代理;SOCKS5 还支持 UDP
透明代理通过网络基础设施拦截或转发符合规则的流量企业网关、网络管理
反向代理代理位于服务器前方,代表后端服务器接收请求Nginx、负载均衡、CDN

特别注意:HTTPS 代理和 HTTPS 解密代理不是同一个概念。

  • HTTPS 代理可以只加密客户端到代理的连接。
  • Charles 这类解密代理,可以在配置允许的情况下,作为 TLS 中间端点分别与客户端和目标服务器握手,进而查看 HTTP 明文。
  1. 正向代理与反向代理

正向代理代表客户端访问外部服务器。客户端通常知道自己在使用代理。

例:Charles、SOCKS5 出口代理

反向代理代表后端服务器接收客户端请求,客户端通常只看到代理入口。

例:Nginx、CDN、负载均衡器

四、加餐小补充#

都唠到这份上了,再加点料。

1.端口转发#

这里最重要的基础是:一个网络连接通常由 协议、目标 IP、目标端口 等信息确定。

  • IP 地址:找到哪台设备或网络接口。
  • 端口:找到这台设备上哪个网络服务。
  • 监听(listen):某个程序在特定地址和端口等待连接。
  • 转发(forward):把到达某个入口的连接或数据送往另一个目标。

端口转发(Port Forwarding)可以理解为:给某个网络入口安排一条通往另一个地址和端口的路线。

常见的是adb的两个操作:

# 电脑连接设备上的 8444
adb forward tcp:18444 tcp:8444
# 设备连接电脑上的 18444,设备侧入口为 8444
adb reverse tcp:8444 tcp:18444
# 查看已建立的映射
adb forward --list
adb reverse --list
# 删除指定映射
adb reverse --remove tcp:8444

2.SSH 远程连接和 SSH 隧道#

SSH(Secure Shell)最初主要用于安全地远程登录另一台计算机。它不仅能执行命令、管理服务器,还能通过端口转发建立加密隧道。

执行下面的命令:

ssh user@192.0.2.10

通常发生以下过程:

  1. 客户端连接远程主机的 SSH 服务,默认 TCP 端口是 22。
  2. 双方协商加密算法和会话密钥。
  3. 客户端验证服务器主机密钥;首次连接时,通常需要核对指纹。
  4. 用户通过密码、公钥等方式完成身份认证。
  5. SSH 在加密连接里传递终端命令和输出。

需要区分两种密钥:

  • 服务器主机密钥:帮助客户端确认连接的是预期的 SSH 服务器。
  • 用户身份密钥:例如客户端的 SSH 私钥,用来证明用户有登录权限。

SSH 加密保护的是 SSH 会话。它不意味着远端计算机上的所有网络流量都会自动经过 SSH。

3.Nat#

NAT 是 Network Address Translation,也就是网络地址转换。它通常运行在路由器或网关上,修改经过它的 IP 地址,有时也会修改 TCP/UDP 端口。

比如家庭网络,通过NAT(也就是路由器)把源地址和端口转换为公网侧映射

内网:192.168.1.20:51000
↓ NAT
公网:203.0.113.5:62001

NAT 和端口转发的区别

这两个概念很容易混淆。

对比NAT端口转发
主要作用转换网络地址或端口把特定入口导向指定目标
常见用途内网设备访问互联网外部访问内网服务
是否一定要手动配置不一定静态端口转发通常需要
是否加密数据不会不会

比如在路由器这么配置:公网地址:8443 → 192.168.1.20:443

那么访问公网地址的 8443 端口,流量会被送到内网服务器的 443 端口。这通常叫静态端口转发,常用于 NAT 网关后的服务器。

但要注意:如果你的网络处于运营商级 NAT(CGNAT)之后,即使在自家路由器配置了端口转发,互联网用户也可能无法直接连进来。

这时可能需要公网 IP、VPN、反向隧道或具有公网入口的中继服务器。

4.桥接模式#

桥接(Bridge)主要解决的是把不同的网络接口连接起来,让它们在同一个二层网络中通信。

可以先把它理解成交换机:设备插在同一个交换网络里,能够通过 MAC 地址转发以太网帧。

桥接和 NAT 的差别

  • 桥接:主要在二层转发帧,通常不做三层地址转换。
  • 路由:根据 IP 路由表,在不同 IP 网络之间转发数据包。
  • NAT:在转发过程中修改地址或端口信息。

虚拟机或模拟器网络常见几种模式:

  • NAT 模式:虚拟设备通过宿主机访问外网,外部设备通常不能直接主动连接虚拟设备。
  • 桥接模式:虚拟设备像局域网中的独立设备一样获得地址,具体能力取决于虚拟化软件和网络环境。
  • 端口映射:为虚拟设备或宿主机上的某个服务建立特定入口。
  • ADB 转发:通过 ADB 调试连接建立端口通道。

5.CDN乱入#

CDN 是 Content Delivery Network,中文叫内容分发网络。

它把网站内容缓存或部署在多个地理位置的边缘节点上,让用户通常可以从较近的节点获取内容。

访问流程大致是:

  1. 客户端解析域名,得到一个或多个可用地址。
  2. 客户端连接某个 CDN 边缘节点。
  3. 如果节点有缓存,可能直接返回内容。
  4. 如果没有缓存,节点可能从源站获取内容,再返回给客户端。

实际调度不一定只由 DNS 决定,也可能结合 Anycast、负载均衡和 CDN 自身的路由机制。

CDN 与反向代理两者有关联,但不是同义词。

  • 反向代理:代表后端服务器接收客户端请求,再转发给后端。
  • CDN:重点在分布式边缘节点、内容缓存、加速和流量调度。
  • 源站(Origin):实际提供原始内容或业务数据的后端服务。

CDN 也能代理动态 API 请求,因此它不只是图片、视频的缓存服务。

6.SOCKS 是什么?和 HTTP 代理有什么区别?#

SOCKS 是一种代理协议。客户端把“我要连接哪个目标地址和端口”的请求交给代理服务器,由代理服务器代表客户端建立连接。

最常见的是 SOCKS5。

项目SOCKS5HTTP 代理VPN
工作层次(概念上)通用代理接口HTTP 应用代理IP 层隧道为主
转发内容TCP,也可支持 UDPHTTP;HTTPS 通常使用 CONNECT 隧道IP 数据包
是否自动加密不会不会自动加密代理链路通常加密设备到 VPN 端点的隧道
需要应用配合通常需要通常需要或由系统代理配置常由系统网络路由接管

SOCKS5 本身不负责加密。 如果你把 TLS 连接交给 SOCKS5 代理,TLS 仍然可以在客户端与最终服务器之间建立;代理通常只是转发 TLS 字节流。

比如

App
│ TLS 加密
▼
SOCKS5 代理
│ 转发加密数据
▼
HTTPS 服务器

7.WebSocket 是什么?#

WebSocket 是一种支持双向通信的协议。连接建立后,客户端和服务器双方都可以主动发送消息,不必每次都重新发起一个 HTTP 请求。

它常见于实时聊天、在线状态、游戏、行情推送和实时控制。

普通 WebSocket 常用 ws://,加密 WebSocket 常用 wss://。

  • ws://:通常使用普通 TCP 连接。
  • wss://:在 WebSocket 通信外使用 TLS 加密。

经典 WebSocket 建连会先发送一个 HTTP Upgrade 请求,然后把连接升级为 WebSocket 协议。现代 HTTP/2 和 HTTP/3 也有相应的 WebSocket 扩展机制,因此并非所有 WebSocket 都必须采用 HTTP/1.1 Upgrade 方式。

典型的 HTTP/1.1 握手看起来像这样:

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ...
Sec-WebSocket-Version: 13

服务器同意后返回 101 Switching Protocols,连接随即进入 WebSocket 数据交换阶段。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ssl pinning以及计算机网络知识笔记
https://fatdog.20060113.xyz/posts/ssl-pinning/
作者
神秘大胖狗
发布于
2026-10-18
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00