You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS应用SSL流量解密求助:Mac拦截加密流量无法解密

解决iOS URLSession SSL流量解密问题的方案

遇到这种SSL解密失败的情况,大概率是证书信任、ATS配置或者App自定义证书校验逻辑在搞鬼,结合你用基础URLSession实现的情况,给你几个针对性的解决方案:

  • 确认证书的全链路信任
    别只在Mac上导入PKCS12证书,iOS设备上也必须安装这份证书,并且一定要在「设置>通用>关于本机>证书信任设置」里开启对该证书的完全信任(iOS 10及以上版本必须手动开启这一步)。另外Mac钥匙串里的证书,要把SSL项设置为「始终信任」,避免抓包工具无法调用证书解密。

  • 调整App的ATS配置
    安全升级后ATS(App Transport Security)的限制可能更严格了,你需要在Info.plist里针对自有域名做例外配置:
    添加NSAppTransportSecurity字典,里面嵌套NSExceptionDomains,把你的域名作为key,设置下面几个子项:

    • NSExceptionAllowsInsecureHTTPLoads:设为YES(临时测试用,正式环境记得改回NO)
    • NSExceptionRequiresForwardSecrecy:设为NO
    • NSIncludesSubdomains:设为YES(如果有子域名的话)
      这样ATS就不会阻止抓包工具的证书交互了。
  • 临时修改URLSession的证书校验逻辑
    如果你的App代码里实现了URLSessionDelegatedidReceiveChallenge方法做自定义证书验证,那抓包工具的证书会被拒绝。测试阶段可以临时修改这段代码,允许信任所有证书(注意只在测试环境用,正式上线必须删掉):

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        // 仅针对服务器信任挑战跳过验证
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            guard let serverTrust = challenge.protectionSpace.serverTrust else {
                completionHandler(.cancelAuthenticationChallenge, nil)
                return
            }
            let credential = URLCredential(trust: serverTrust)
            completionHandler(.useCredential, credential)
            return
        }
        // 其他挑战按默认逻辑处理
        completionHandler(.performDefaultHandling, nil)
    }
    
  • 换用针对性的抓包工具
    既然ZAP和Burp暂时不好用,可以试试这两个工具:

    • Charles Proxy:对iOS SSL抓包的支持非常成熟,导入你的PKCS12证书后,在「SSL Proxying Settings」里添加你的域名,然后在iOS设备上配置Charles的代理,安装Charles的根证书并信任,基本就能解密流量了。
    • mitmproxy:开源的命令行抓包工具,灵活性很高,通过命令行导入你的PKCS12证书,配置代理后就能拦截解密,适合喜欢折腾的开发者。
  • 检查抓包工具的SSL配置细节
    如果还是用Burp,确保这几点:

    1. 在「Proxy > Options > SSL Certificate」里导入你的PKCS12证书
    2. 在「Target > Scope」里添加你的自有域名,确保勾选了「Include in scope」
    3. 确认「Proxy > Intercept」是开启状态,并且SSL解密功能没有被禁用

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

火山引擎 最新活动