1. SSL Pinning 原理与支付安全背景
1.1 证书锁定概念
SSL Pinning(证书锁定)是一种强化 TLS 通信安全的机制,它将客户端可信任的证书或公钥“锁定”在应用内部,拒绝任何未在锁定列表中的 CA 签发的证书。即使设备受信任根证书列表被篡改,或攻击者使用了合法 CA 签发的欺诈证书,Pinning 仍能阻断连接。
核心思想:客户端不再盲目信任系统根存储区,而是只信任预先嵌入的特定证书、公钥哈希或 SPKI(Subject Public Key Info)。
| 对比维度 | 普通 SSL/TLS 验证 | SSL Pinning |
|---|---|---|
| 信任基础 | 设备根证书存储区 + CA 链 | 应用内预置的固定证书/公钥 |
| 中间人攻击抵抗力 | 弱(CA 被攻破或添加恶意根时失效) | 强(即使系统根被篡改也不受影响) |
| 部署复杂度 | 无额外配置 | 需在客户端嵌入并维护锁定信息 |
| 证书更换影响 | 无影响(服务器换新 CA 即可) | 必须同步更新客户端应用的锁定指纹 |
1.2 中间人攻击威胁
中间人攻击(Man-in-the-Middle, MITM)是支付场景中最危险的网络攻击之一。攻击者在客户端与服务器之间拦截、解密、篡改或重放数据。常见手段包括:
- 伪造 Wi-Fi 热点并部署自签名根证书;
- 向设备植入恶意 CA 证书(如通过恶意应用或系统漏洞);
- 利用已知 CA 漏洞签发假冒服务器证书(如 CNNIC、DigiNotar 事件)。
支付 SDK 风险:一旦通信被劫持,攻击者可窃取卡号、CVV、令牌或篡改订单金额,造成直接资金损失与合规违规。
1.3 支付 SDK 通信安全要求
支付行业对通信安全有严格的合规与风控标准,主要包括:
- PCI DSS:要求在公网传输持卡人数据时必须使用强加密(TLS 1.2+),并限制客户端信任范围;
- 防重放与篡改:支付请求必须与服务器进行双向认证,防止中间人篡改订单、金额或令牌;
- 证书固定:大部分支付 SDK(如 Stripe、Braintree、支付宝、微信支付)均强制或推荐使用 SSL Pinning;
- 证书更换策略:需支持热更新或提前注入备用证书指纹,避免因服务器证书更新导致 App 大面积不可用。
实现建议:支付 SDK 应在编译期将服务器公钥的 SHA-256 哈希写入资源文件,并在连接建立时通过
X509TrustManager(Android)或 URLSessionDelegate(iOS)进行校验。
典型 Android 网络安全配置文件示例(res/xml/network_security_config.xml):
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">pay.example.com</domain>
<pin-set expiration="2026-01-01">
<pin digest="SHA-256">47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=</pin>
<pin digest="SHA-256">2+U6xU6v+1W8j9X2Gc5kQ1F3z5qX5Yz0x4b6c8d9e0=</pin>
</pin-set>
</domain-config>
</network-security-config>
该配置将 pay.example.com 的证书指纹锁定为两枚预置哈希,任何不匹配的服务器证书都将导致连接失败。