跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Objective-C大前端

iOS 网络安全实战:HTTPS 通信与证书锁定防抓包

综述由AI生成探讨了 iOS 应用中 HTTPS 通信的安全机制,分析了自签名证书与权威机构证书的区别,揭示了使用 Charles 等代理工具进行中间人攻击的风险。重点介绍了如何通过配置 Info.plist 白名单及在 AFNetworking 中实施公钥绑定(Certificate Pinning)来严格验证服务器身份,有效防止数据被窃听或篡改,确保移动应用网络传输的安全性。同时提供了具体的代码示例和 OpenSSL 证书转换步骤,帮助开发者构建更安全的网络层防御体系。

协议工匠发布于 2025/2/6更新于 2026/4/255 浏览
iOS 网络安全实战:HTTPS 通信与证书锁定防抓包

iOS 应用网络安全之 HTTPS

安全套接字层(Secure Socket Layer, SSL)是实现互联网安全通信的最普遍标准。Web 应用程序使用 HTTPS(基于 SSL 的 HTTP),HTTPS 使用数字证书来确保在服务器和客户端之间进行安全、加密的通信。在 SSL 连接中,客户机和服务器在发送数据之前都要对数据进行加密,然后由接受方对其进行解密。

1. HTTPS 握手流程

当浏览器(客户端)需要与某个安全站点建立连接时,先建立 TCP 连接(三次握手),然后再发生 SSL 会话握手:

  1. 请求:浏览器通过网络发送请求安全会话的消息(通常以 https 而非 http 开头的 URL)。
  2. 响应:服务器通过发送其证书(包括公钥)进行响应。
  3. 验证:浏览器检验服务器的证书是否有效,是否由其位于浏览器数据库中的可信 CA 签发,以及 CA 证书是否已过期。
  4. 密钥交换:如果证书有效,浏览器生成一个一次性的会话密钥,并使用服务器的公钥对该会话密钥进行加密后发送给服务器。
  5. 解密:服务器使用其专用密钥对消息进行解密,恢复会话密钥。
  6. 加密通信:握手之后,客户端已验证 Web 站点的身份,双方拥有会话密钥副本,后续所有通信均使用该密钥加密。

上述是普遍的单向验证方式(客户端验证服务端)。也可以做双向验证(服务端也验证客户端),一般用于银行业务(如 U 盾)。本文主要关注普遍的单向验证方式的应用。

2. iOS 移动开发 HTTPS 应用现状

当下绝大多数的移动互联网项目都采用 HTTP、HTTPS 协议作为前后端的数据接口协议。在 iOS 开发群体中,绝大部分都在项目中应用了第三方开源的 HTTP 请求框架 AFNetworking 来快速高效地开发。

从 iOS 9.0 开始,Apple 默认只允许采用经过权威证书颁发机构签名的证书的 HTTPS 站点的访问。一切是为了安全。开发者需要在 Info.plist 中设置 App Transport Security 才能加载非 HTTP 的资源,或者配置例外域名。

HTTPS 的服务器配置的证书分两大类:

  • 权威机构签名颁发的证书:通常需要购买服务,也有少数机构提供免费证书(如 Let's Encrypt, WoSign)。
  • 自签名证书:服务器配置的是研发人员自己签名生成的证书,常用于内部测试环境。

3. AFN 调用使用权威机构颁发证书的 HTTPS 接口

AFNetworking 框架修复了 SSL 中间人攻击漏洞,并强烈要求开发者使用公钥绑定或者证书绑定的安全策略。正确使用 AFNetworking 请求这类证书的 HTTPS 站点代码如下:

AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
policy.validatesDomainName = YES;
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy = policy;
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

对于这类证书的站点,Info.plist 都不需要特殊设置,因为已经是权威机构颁发的证书了。我们只需要设置验证绑定方式和验证域名以防止中间人攻击。

4. AFN 调用使用我们自己签名证书的 HTTPS 接口

对于使用自签名证书的站点,浏览器打开 web 站点也会默认阻止访问,除非用户手动把该站点加入信任列表。这个手动加入的过程其实就是不去验证服务器的合法性,任性地认为服务器是可信赖的。

如果在 App 端不严格验证,虽然可以成功访问目标服务器返回数据,但中间很有可能返回的数据不是真正的目标服务器返回的数据,也可能是网络传输中间的第三者伪装返回的数据。传输的数据被人窃取甚至篡改都是很可能的。

4.1 不正确的做法

浏览器手动加入自签名站点到信任列表的操作,相当于 iOS 开发中 AFNetworking 的 API 如下设置:

  1. Info.plist 设置:
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    
  2. AFNetworking 代码设置 SecurityPolicy:
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 允许非权威机构颁发的证书
    manager.securityPolicy.allowInvalidCertificates = YES;
    // 也不验证域名一致性
    manager.securityPolicy.validatesDomainName = NO;
    // 关闭缓存避免干扰测试
    manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    
    [manager GET:@"https://your-domain.com/api" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
        NSLog(@"%@", responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
    }];
    

经过如上两步设置之后,可以在 iOS 应用中访问采用自签名证书的 HTTPS 站点。但是这个是不安全的,因为它在没有使用 HTTPS/SSL 代理和使用像 Charles 那样的 HTTPS/SSL 代理的情况下都可以访问服务器资源。这只能防止'君子'在网络中用 Wireshark 之类来 TCP 抓包嗅探,因为毕竟还是 HTTPS 加密了传输数据。但这不能防止中间人攻击!例如用户可以给手机设置 HTTPS 的 SSL 代理(比如 Charles),完全可以在代理中看到明文数据。

4.2 正确的做法:证书锁定(Certificate Pinning)

要在 App 端严格验证服务器的合法性,防止网络中间的代理或者防火墙进行中间人的攻击和证书欺骗,我们需要把服务器配置的证书打包到客户端程序中(私钥留服务器不要分发,非常重要),在代码里去读取该证书/公钥信息和服务器返回的进行匹配验证。

步骤一:配置 Info.plist 白名单

从 Xcode 7 和 iOS 9 开始,Apple 提升了 App 的网络安全性。App 默认只能进行对采用权威机构签名颁发证书的 Web 站点进行访问。自签名证书的 HTTPS 站点属于例外,所以需要在 App 的 Info.plist 中单独为域名设置 Exception Domains 白名单,而不是打开 Allow Arbitrary Loads 全部放开。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>tv.diveinedu.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

建议使用白名单模式,仅针对特定域名放开,而不是全局放开。

步骤二:实施证书锁定

要做到严格验证防止像 Charles 那样的中间人代理抓包,AFNetworking 代码应该使用公钥绑定模式。将服务器端配置的包含公钥的证书分发到客户端后,需要转换为 DER 格式的证书文件。

  1. 转换证书格式: 使用 OpenSSL 命令将 .crt 转换为 .der:

    openssl x509 -outform der -in tv.diveinedu.com.crt -out tv.diveinedu.com.der
    

    将生成的 .der 文件添加到 Xcode 项目的 Bundle 中。

  2. 代码实现:

    NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@"tv.diveinedu.com" ofType:@"der"];
    NSData *certData = [NSData dataWithContentsOfFile:certFilePath];
    NSSet *certSet = [NSSet setWithObject:certData];
    
    AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:certSet];
    policy.allowInvalidCertificates = YES; // 允许自签名,但需配合 pinning 验证
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.securityPolicy = policy;
    manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    
    [manager GET:@"https://tv.diveinedu.com/api" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
        NSLog(@"%@", responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
    }];
    

上面的代码能够验证服务器身份。在没有使用代理的时候可以正常访问服务器的资源,但是一旦用户给手机网络设置了如 Charles 那样的 HTTPS/SSL 代理服务,则会出现服务器证书验证失败,SSL 网络连接会断开。这样就达到了防止中间人攻击的效果,老板再也不用担心数据接口被人抓包或者代理给扒出来了。

5. 总结与建议

在移动端开发中,仅仅开启 HTTPS 并不足以保证绝对安全。为了防止中间人攻击和数据泄露,建议遵循以下最佳实践:

  1. 优先使用权威证书:生产环境务必申请并部署由权威 CA 机构签发的证书。
  2. 实施证书锁定:对于必须使用自签名证书的场景(如内网测试),务必在客户端实现证书锁定(Pin),确保只有特定的公钥或证书能被信任。
  3. 最小化权限配置:Info.plist 中尽量使用白名单机制,避免全局允许任意 HTTP 加载。
  4. 定期更新证书:注意证书的有效期,及时更新过期的证书,防止因证书失效导致的服务不可用或被利用。
  5. 原生方案替代:随着 AFNetworking 维护频率的变化,新项目可考虑使用系统原生的 NSURLSession 配合 URLSessionDelegate 来实现更底层的证书验证逻辑。

通过上述措施,可以有效提升 iOS 应用的网络通信安全性,防止敏感数据在传输过程中被窃听或篡改。

目录

  1. iOS 应用网络安全之 HTTPS
  2. 1. HTTPS 握手流程
  3. 2. iOS 移动开发 HTTPS 应用现状
  4. 3. AFN 调用使用权威机构颁发证书的 HTTPS 接口
  5. 4. AFN 调用使用我们自己签名证书的 HTTPS 接口
  6. 4.1 不正确的做法
  7. 4.2 正确的做法:证书锁定(Certificate Pinning)
  8. 步骤一:配置 Info.plist 白名单
  9. 步骤二:实施证书锁定
  10. 5. 总结与建议
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 数学可视化:显函数、隐函数及复杂曲线的交互式绘图
  • 大模型商业化:ToB 与 ToC 并非选择题
  • FFT NPainting LaMa 与 Stable Diffusion Inpainting 性能对比评测
  • IntelliJ IDEA 关闭 AI 自动代码补全提示的设置步骤
  • Java+Leaflet 实现湖南省道路长度 WebGIS 系统
  • OpenClaw 本地部署与飞书机器人接入教程
  • 2025 AI 问道之旅:个人成长与深度学习理解
  • 基于 Vue + Three.js 构建 Sonic 数字人前端交互预览系统
  • Electron 前端开发快速入门教程:从零搭建到打包部署
  • I2C 时钟延展:从设备如何优雅暂停通信
  • LeetCode 128:哈希集合求解最长连续序列
  • Qwen-Image-2512 搭建 AI 绘画工作流指南
  • 基础算法:滑动窗口(Python 实现)
  • 鸿蒙金融理财全栈项目:生态合作、用户运营与数据变现优化
  • Emotion2Vec+ Large 语音情感识别 WebUI 界面优化实战
  • 使用 KSWEB 在安卓手机部署 Typecho 博客并配置外网访问
  • Agent AI 探索多模态交互前沿领域综述(一)
  • PaperRed——2026年AI论文写作、AI降重、降低aigc,免费查重的网站
  • 远程控制 OpenClaw:从群晖 Docker 到本地浏览器的完整隧道指南
  • Hunyuan-MT-7B-WEBUI 远程访问配置与安全策略

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online