You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在Swift Network Framework中实现证书固定(Cert Pinning)

在Network Framework中实现证书固定的完整方案

你可以通过SecTrust对象提取服务器证书,完成自定义证书固定逻辑,以下是可直接复用的实现方案:

核心实现逻辑

  1. 预先将目标服务器的证书哈希(推荐SHA256)或证书数据存入本地(可硬编码或从资源文件读取)
  2. 在sec_protocol_options_set_verify_block回调中,从SecTrust提取服务器证书链
  3. 对比服务器证书与本地存储的固定值,验证通过则完成信任校验

完整代码示例

// 预先存储的服务器证书SHA256哈希(替换为你的证书实际哈希值)
let pinnedCertSHA256 = "ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890"

sec_protocol_options_set_verify_block(options.securityProtocolOptions, { (metadata, secTrust, complete) in
    let trust = sec_trust_copy_ref(secTrust).takeRetainedValue()
    
    // 1. 从SecTrust中获取服务器证书链的叶子证书(第一个证书)
    guard let serverCert = SecTrustGetCertificateAtIndex(trust, 0) else {
        complete(false)
        return
    }
    
    // 2. 提取证书的SHA256哈希
    guard let certData = SecCertificateCopyData(serverCert) as Data? else {
        complete(false)
        return
    }
    let sha256Digest = SHA256.hash(data: certData)
    let serverCertHash = sha256Digest.compactMap { String(format: "%02x", $0) }.joined()
    
    // 3. 对比固定的哈希值
    let isPinnedCertValid = serverCertHash.lowercased() == pinnedCertSHA256.lowercased()
    
    if isPinnedCertValid {
        // 证书固定验证通过,同时执行系统信任校验(可选,根据业务需求调整)
        var error: CFError?
        if SecTrustEvaluateWithError(trust, &error) {
            complete(true)
        } else {
            complete(false)
        }
    } else {
        // 证书不匹配,拒绝建立连接
        complete(false)
    }
}, DispatchQueue.global())

关键细节说明

  • 获取证书哈希:将服务器证书导出为DER格式后,可通过终端命令计算SHA256:openssl dgst -sha256 -binary your-cert.cer | xxd -p -c 256
  • 证书链选择:若需固定中间证书或根证书,调整SecTrustGetCertificateAtIndex的索引值即可(索引0为叶子证书,索引越大越靠近根证书)
  • 系统校验取舍:如果业务仅要求证书固定,可跳过SecTrustEvaluateWithError直接根据哈希对比结果调用complete,但保留系统校验能避免额外安全风险
  • 测试环境逻辑:allowInsecure分支仅用于测试,生产环境必须移除,禁止绕过证书校验

内容的提问来源于stack exchange,提问作者Natto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:20:35