使用HTTPS已经是个大的趋势了,未来肯定也是全站HTTPS。Apple也规定所有开发者在2017年1月1日前,要开启ATS功能(App Transport Security),它会强制App在连接Web服务时经过HTTPS链接而不是 HTTP,以保护用户数据在传输过程中的安全。
HTTPS能有效的防止中间人攻击,前提是App做好证书校验。但是很多APP用上了HTTPS,但并未做做证书校验,这样其实是没什么意义的。
如果网络层使用AFN,那么直接把证书放入App中就好了,AFN会读取App中的所有证书进行校验。HTTPS效率上肯定不如HTTP,但是安全性是不可比的,如果用上HTTPS,都建议校验完整的证书链。
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
AFN中一句代码即可。
这样有很高的安全性,但是维护成本却很高了很多。因为证书是有有效期的,如果服务器证书过期,更换新证书,App不升级那么就不能继续使用了,这并不是一个好的用户体验。
有没有什么一劳永逸的方法呢?
比如像浏览器那样,拿到服务器的证书,然后去CA进行校验。方法听上去很棒,但是Apple并没有这样的API。官方文档中只有这样一句话。
"Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors).Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
也就是说Apple希望你把证书打包放进App中,那就只能在想其他方法了。
从服务器把证书载下来,先生成一对RSA的公私钥,公钥硬编码在App中,私钥放在服务器。HTTPS握手前通过服务器下发证书信息(公钥,签名,机构等),下发的信息服务器使用私钥进行签名,通过App中的公钥验签存在内容中后,然后发起正常的HTTPS请求,对比两个证书信息是否一致进行证书校验。但是这样做效率低太多,而且很复杂。