WWDC2016 开发者大会上 Apple 曾宣布自2017年起 AppStore 中的所有 App 都必须启用 ATS 安全功能。启用 ATS 后, 明文 HTTP 资源加载将被屏蔽, App 需通过 HTTPS 连接网络服务,实现传输加密,保障用户数据安全。
虽然上述条款已被无限期 Delay,但是从中可以投射出 Apple 对于传输数据安全的重视。Apple 为什么要限制 HTTP?
因为 HTTP 通过明文传输,没有经过任何安全处理,且很容易受到中间人攻击,比如:通过重定向把客户端的请求转到一个李鬼服务器;查看客户端敏感信息;或者偷偷修改客户端的请求/响应数据包。所以 Apple 才迫切地想要引入 HTTPS。
那 HTTPS 如何来保证传输安全?HTTPS ( HTTP over SSL) 即基于安全套接字层的超文本传输协议,是最初由 Netscape 开发的 Web 协议。
HTTPS 握手流程:
HTTPS 在 HTTP 基础上添加了SSL/TLS加密传输协议,其握手流程大概如下:
1)客户端—>服务器 发起请求
客户端发起请求到服务器。主要参数是支持的协议版本,加密方法还有随机数n1;
2)服务器 收到请求
服务器收到请求并确认加密方法,并返回公钥,还有一个由服务器生成的随机数n2;
3)服务器—>客户端 发送证书,客户端验证证书
这部分工作在 iOS 中 CA 认证的证书会自动验证,而私有证书则需要手动验证放行,否则拒绝连接;
4)客户端—>服务器 发送信息
客户端验证证书成功后会生成第三个随机数n3,并用第2步服务器返回的证书对该随机数加密,并发送给服务器,同时也会发送一些其他信息比如:编码信息和客户端握手结束通知。
5)服务器—>客户端 发送信息
服务器用私钥解密后,得到客户端传来的第三个随机数n3,两端使用这三个随机数n1,n2,n3来生成“Session Key”。服务器向客户端发送编码信息和服务器握手结束通知。
6)完整性验证
完整性验证成功之后,后面的信息传输就靠这个“Session Key”进行对称加密了。
SSL 在握手的过程中主要交换了以下三个信息:
加密通信协议:就是双方商量使用哪一种加密方式,假如两者支持的加密方式不匹配,则无法进行通信。
数字证书:该证书包含了公钥等信息,一般是由服务器发给客户端,接收方通过验证这个证书是不是由信赖的 CA 签发,或者与本地的证书相对比,来判断证书是否可信;假如需要双向验证,则服务器和客户端都需要发送数字证书给对方验证。
三个随机数n1,n2,n3:这三个随机数构成了后续通信过程中用来对数据进行对称加密解密的“对话密钥”。
中间人攻击:
中间人攻击是通过与客户端、服务器分别建立连接,来获得了明文的信息的攻击方式。在这个过程中,客户端与服务器的通信被第三方解密、查看、修改。
为什么有一些 APP 即便使用了 HTTPS,还是会被中间人攻击呢?
基本上的都是因为没做客户端验证,特别是在使用未经 CA 认证的证书时,更容易中招。关于黑客是如何在协议握手初期劫持服务,从而实现中间人攻击,我们可以做如下推演:
黑客劫持到服务器公钥,并冒充客户端与服务器连接;
黑客自己生成公钥冒充服务器公钥返回给真正的客户端;
如果客户端未做验证的话,就不会发现证书被替换,于是客户端会用黑客的公钥加密发送数据;
黑客劫持数据后,用自己的私钥解密,查看或者篡改;
黑客用真正的服务器公钥加密篡改后的数据与服务器进行通讯。
由此可以看出,我们需要做好客户端验证,比如:把证书打包进 APP,然后与服务器返回的证书作对比验证,验证成功才允许连接。
当然使用这种方式也会导致一些问题,比如:当证书过期时 APP 连不上服务器,这时可能需要我们提前把新证书打包进 APP 中,来实现无缝切换。
结语
由于 iOS 平台的封闭性,许多 iOS 开发人员在安全性方面没有进行深入。
实际的做为 iOS 开发者,我们需要在理解 HTTPS 的基础上,来确保连接的安全性,给传输数据上把锁。
本文作者:魏金豹(点融黑帮),现任点融工程部高级移动开发工程师。