1️⃣ HTTPS 常见安全风险
| 风险类型 | 描述 | 面试考点 |
|---|---|---|
| 中间人攻击(MITM) | 攻击者截取通信,篡改或窃取数据 | HTTPS 证书验证、证书 pinning |
| 证书伪造或信任链问题 | 使用无效、过期、伪造证书 | ATS(App Transport Security)、证书有效性检查 |
| 弱加密套件 | 使用已知不安全的算法(如 RC4、MD5) | TLS 强制版本、套件选择 |
| 过期证书或自签名证书 | 用户或服务器未更新证书 | 证书自动更新、严格验证 |
| DNS 污染 / 劫持 | 域名解析被篡改,访问恶意服务器 | DNS over HTTPS (DoH)、验证主机名 |
| 降级攻击(Protocol Downgrade) | 强制客户端使用 HTTP/1.0 或低版本 TLS | ATS 强制 TLS 1.2+ |
| 敏感信息泄露 | URL、Header 或日志中包含敏感数据 | 避免在 URL 中传递密码或 Token |
| Replay 攻击 | 拦截请求并重复发送 | Token、时间戳、一次性请求签名 |
2️⃣ iOS 开发中的防护措施
(1) App Transport Security (ATS)
-
iOS 默认要求 HTTPS,禁用明文 HTTP。
-
ATS 规则:
- TLS 版本 ≥ 1.2
- 强加密套件(AES、SHA-2)
- 禁止自签名证书
-
配置方式:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
(2) 证书校验 / Pinning
- 定义:应用只信任指定证书或公钥,防止 MITM。
- 实现方式:
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if let serverTrust = challenge.protectionSpace.serverTrust,
SecTrustEvaluateWithError(serverTrust, nil) {
// 获取服务器证书或公钥
let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0)!
let serverCertData = SecCertificateCopyData(serverCert) as Data
// 本地证书
let localCertData = NSData(contentsOfFile: Bundle.main.path(forResource: "server", ofType: "cer")!)! as Data
if serverCertData == localCertData {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
return
}
}
completionHandler(.cancelAuthenticationChallenge, nil)
}
(3) 严格主机名验证
- 确保
challenge.protectionSpace.host与请求 URL 完全匹配。 - 避免伪造服务器或 DNS 污染。
(4) 敏感信息保护
- 不要在 URL 中传递敏感信息(如密码、Token)。
- 使用 HTTP Body + HTTPS POST 传输敏感数据。
- 避免将敏感信息写入日志或缓存。
(5) 使用现代加密套件
- 强制 TLS ≥ 1.2,禁用 RC4、MD5 等弱算法。
- iOS ATS 默认配置已经符合此要求。
(6) Replay 攻击防护
- 请求签名 + 时间戳
- Token 过期策略
- Nonce(随机数)保证每次请求唯一性
(7) 自动更新证书和 CRL/OCSP 检查
- 确保证书未过期、未吊销。
- iOS 的
URLSession会自动验证证书链,但自签名或 pinning 时需手动更新证书。
3️⃣ 面试加分点
-
理解 HTTPS 安全不仅是加密,还包括:
- 证书验证
- 主机名验证
- ATS 强制策略
- 敏感信息处理
- Replay 攻击防护
-
熟悉 URLSessionDelegate 的证书校验实现 是必备技能。