一句话结论:ATS(App Transport Security,苹果的应用传输安全策略)默认只允许加密连接,App 里如果用明文 HTTP(HyperText Transfer Protocol,超文本传输协议,也就是不带加密的常规网页请求地址)或者用了老旧的加密协议,请求会在建立连接这一步就被系统掐掉,表现为”服务器没问题但 App 一直转圈”。
这套策略默认管什么
从 iOS 9 开始,苹果对新建工程默认开启了这套策略,大意是:App 发起的网络请求必须走 TLS(Transport Layer Security,传输层加密协议),并且版本和加密套件要达到一定的安全水位。
落到具体表现上,被拦下来的请求通常满足以下一条或多条:
- 用的是 http:// 开头的明文地址,没有做任何豁免配置。
- 服务端用的是很早版本的 TLS,或者配置了已经被认为不安全的加密套件。
- 服务器证书是自签的,或者证书链不完整。
- 域名没有走正规的证书颁发机构,无法完成证书校验。
它和签名有没有关系
没有直接关系。签名改的是安装凭证层,ATS 是系统运行时的网络策略层,两者互不干涉。一个 App 在 App Store(苹果官方应用商店)上架会被拦的请求,签名分发之后同样会被拦。
但有一件事是签名场景下更容易遇到的:并行生命周期长。很多签名分发的 App 是内部工具或者行业应用,后端服务器年头久,TLS 配置一直没升级。上架的产品因为有审核和用户投诉压力,服务端会跟着升级;分发的版本往往没人盯着这块,于是在新系统上线后突然连不上。
排查的正确顺序
遇到 App 网络不通,先分清是”完全连不上”还是”连上了但没数据”,两种情况的排查路径完全不同。下面是按成本从低到高排的顺序:
第一步,用手机自带浏览器直接访问接口地址。浏览器不受 App 的 ATS 配置约束,但会明确提示证书不受信任或者连接不安全。如果浏览器也打不开,问题在服务端或者网络环境,不在 App。
第二步,看是不是明文地址。把完整的接口域名拷出来看开头。如果是 http://,在默认配置下一定被拦,这是最快能确认的一种。
第三步,查服务端 TLS 配置。用在线检测工具输入域名,能看到支持的协议版本和加密套件列表。每年 iOS(苹果移动操作系统)大版本升级都会抬高对加密协议的最低要求,老服务器很容易在某个系统版本之后掉出合格线。
第四步,看证书链。服务器配证书时如果没把中间证书一起配进来,部分设备会校验失败,部分设备却能正常访问——这种”有的手机能用有的不能用”的现象,几乎都指向证书链不完整。
解决思路有哪些
首选永远是把服务端升级达标:换成受信任的证书、启用 TLS 1.2 及以上版本、配好完整的证书链。这一步做完,不需要动 App 任何配置。
如果服务端确实短期改不了,App 一侧可以对特定域名做例外配置,在 Info.plist(应用配置清单)里声明这批域名允许非加密连接。这是一个需要谨慎使用的口子:范围要精确到具体域名,不要图省事放开全局;并且要清楚这只是过渡方案,服务端迟早要改。
不要采用的办法是彻底关掉校验。有些老代码的做法是在网络库里直接忽略证书错误,这在调试阶段可以临时用,正式分发的包里带着这种代码,等于把通信内容敞开了给同一网络下的其他人看。
顺带提一句企业网络环境
公司内部 Wi-Fi 如果做了流量审计,会用自己的证书去替换服务端证书。这种情况下 App 会因为证书主体对不上而连接失败,换到手机流量下立刻恢复正常。遇到”只有公司网络里不行”的现象,优先怀疑这一层,别急着改代码。
小结
ATS 拦请求和签名无关,问题基本都在服务端或者使用明文地址。排查从手机浏览器开始,四步走完基本能定位;解法优先升级服务端,App 侧的例外配置只能当过渡,关闭校验的做法不要用在正式包里。
我是本期作者小思,想解决苹果企业签名、超级签名、TF签名问题?可以在微信公众号对话框找到我哦~(QQ:822404920 微信:A-mk5888)