iOS应用网络安全之HTTPS

[复制链接]
发表于 2024-11-22 19:14:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
 移动互联网开发中iOS应用的网络安全标题往往被大部分开发者忽略,

iOS9和OS
X
10.11开始Apple也默认进步了安全配置和要求.

本文以iOS平台App开发中对后台数据接口的安全通信举行解析和加固方法的分析.



1.
HTTPS/SSL的基本原理



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



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



  • 浏览器将通过网络发送请求安全会话的消息(通常请求以
    https
    而非
    http
    开头的
    URL)。
  • 服务器通过发送其证书(包罗公钥)举行响应。
  • 浏览器将检验服务器的证书是否有效,并检验该证书是否是由其证书位于浏览器的数据库中的(而且是可信的)CA
    所签发的。它还将检验
    CA
    证书是否已过期。
  • 假如证书有效,浏览器将生成一个==一次性的、唯一的==会话密钥,并使用服务器的公钥对该会话密钥举行加密。然后,浏览器将把加密的会话密钥发送给服务器,如许服务器和浏览器都有一份会话密钥。
  • 服务器可以使用其专用密钥对消息举行解密,然后规复会话密钥。

握手之后,即体现客户端已验证了
Web
站点的身份,而且只有该客户端和
Web
服务器拥有会话密钥副本。从现在开始,客户机和服务器便可以使用该会话密钥对彼此间的所有通信举行加密。如许就确保了客户机和服务器之间的通信的安全性。

上面是一样平常也是应用最普遍的单向验证方式,由浏览器(客户端)来验证服务端的正当性;其实也可以做双向验证,服务器也可以验证浏览器(客户端)的正当性,不过一样平常使用在银行业务上,好比U盾之类。我们现在关注普遍的单向验证方式的应用。

2.
iOS移动开发HTTPS应用近况



当下绝大部份的移动互联网项目都采用HTTP、HTTPS协议作为前后端的数据接口协议。而iOS开发群体中,绝大部分都在项目中应用了第三方开源的HTTP请求框架AFNetworking来快速而高效的开发,毕竟快鱼吃慢鱼的时代嘛。AFNetworking请求HTTP接口简直是简朴得不能再简朴了。只不过从iOS9.0开始需要设置Info.plist中App
Transport
Security打开非HTTP的资源加载,由于Apple默认只允许采用颠末权势巨子证书颁发机构署名的证书的HTTPS站点的访问,齐备是为了安全。安全。安全。

那么我们重点来分析采用HTTPS协议的后台接口的一样平常使用方式:

HTTPS的服务器配置的证书分两大类,一类是颠末权势巨子机构署名颁发的证书,如许证书通常是要花钱买服务的,固然现在也有少数机构提供免费的证书署名服务。另一类就是服务器配置的是研发职员自己署名生成的证书。

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


现在AFNetworking框架已经修复了上半年爆出的SSL中心人攻击漏洞,并强烈要求开发者使用公钥绑定大概证书绑定的安全计谋,那么精确使用AFNetworking请求这类证书的HTTPS站点代码很简朴如下:
  1. AFSecurityPolicy
  2. *policy
  3. =
  4. [AFSecurityPolicy
  5. policyWithPinningMode:AFSSLPinningModePublicKey];
  6. policy.validatesDomainName
  7. =
  8. YES;
  9. AFHTTPSessionManager
  10. *manager
  11. =
  12. [AFHTTPSessionManager
  13. manager];
  14. manager.securityPolicy
  15. =
  16. policy;
  17. manager.requestSerializer.cachePolicy
  18. =
  19. NSURLRequestReloadIgnoringLocalCacheData;
复制代码



对于这类证书的站点,Info.plist都不需要设置,由于已经是权势巨子机构颁发的证书了,我们只需要设置验证绑定方式和验证域名以防止中心人攻击,毕竟申请证书是花了钱(现在也有免费的申请,好比WoSign),省事一点。

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


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

那么手动加入信任列表,如许会导致证书的验证过程压根没发生,虽然可以成功访问目标服务器返回我们需要的数据,其实,这中心很有大概返回的数据不是正真的目标服务器返回的数据,也大概是网络传输中心的第三者伪装返回的数据。传输的数据被人窃取甚至纂改都是很大概的。

4.1
不精确的做法



浏览器手动加入自署名站点到信任列表这个操作的功能相当于iOS开发中AFNetworking的API的如下做法:



  • A
    非权势巨子机构颁发证书的HTTPS请求一样必须先在Info.plist设置如下:
  1.   
  2. <key>NSAppTransportSecurity</key>
  3. <dict>
  4. <key>NSAllowsArbitraryLoads</key>
  5. <true/>
  6. </dict>
复制代码



  B
AFNetworking代码设置SecurityPolicy


  1. AFHTTPSessionManager
  2. *manager
  3. =
  4. [AFHTTPSessionManager
  5. manager];
  6. //允许非权威机构颁发的证书
  7. manager.securityPolicy.allowInvalidCertificates
  8. =
  9. YES;
  10. //也不验证域名一致性
  11. manager.securityPolicy.validatesDomainName
  12. =
  13. NO;
  14. //关闭缓存避免干扰测试
  15. manager.requestSerializer.cachePolicy
  16. =
  17. NSURLRequestReloadIgnoringLocalCacheData;
  18. [manager
  19. GET:@"https://tv.diveinedu.com/channel/"
  20. parameters:nil
  21. progress:nil
  22. success:^(NSURLSessionDataTask
  23. *
  24. _Nonnull
  25. task,
  26. id
  27. _Nullable
  28. responseObject)
  29. {
  30. NSLog(@"%@",responseObject);
  31. }
  32. failure:^(NSURLSessionDataTask
  33. *
  34. _Nullable
  35. task,
  36. NSError
  37. *
  38. _Nonnull
  39. error)
  40. {
  41. NSLog(@"%@",error);
  42. }];
复制代码



颠末如上两步设置之后,我们可以在iOS应用中访问我们采用自署名证书的HTTPS站点了。但是这个是不安全的,由于他在没有使用HTTPS/SSL代理和使用像Charles那样的HTTPS/SSL代理的情况下都可以访问服务器资源.
完全可以说是白费功夫,只能防止“君子”在网络中用Wireshark之类来TCP抓包嗅探。由于毕竟还是HTTPS加密了传输数据了。那为什么我要说如许是白费功夫呢,由于这个办法不能防止中心人攻击!好比用户可以给手机设置HTTPS的SSL代理(好比Charles),完全可以在代理中看到明文数据,所以,既然用了HTTPS就要防止中心人攻击,不然还不如不用HTTPS。

下面我们来看看怎么用Charles代理抓包工具所抓到的HTTPS传输的数据:





Charles代理抓包

上图是在Mac上运行Charles工具代理抓包,真机和Mac电脑同一个局域网,并设置代理为Mac机的IP和Charles的代理端口8888,然后启动App请求网络后抓到的数据。是不是很意外啊。HTTPS的数据也抓出明文了。

显然如许黑白常不安全的,那么当我们使用自署名证书的时间,我们该如何来在App端(客户端)严格的验证服务器的正当性呢?

4.2
精确的做法



我们要在App端严格验证服务器的正当性,防止网络中心的代理大概防火墙举行中心人的攻击和证书欺骗,那么我们需要把服务器配置的证书打包到客户端程序中(私钥留服务器不要分发不用泄露,非常紧张),在代码里去读取该证书/公钥信息和服务器返回的举行匹配验证.

在iOS开发中,从Xcode7和iOS9开始,Apple提升了App的网络安全性,App默认只能举行对采用权势巨子机构署名颁发证书的Web站点举行访问(信任的HTTPS),而自署名的证书的HTTPS站点也被列为属于例外,所以我们需要在App的Info.plist中单独为我们的域名设置Exception
Domains"白名单",而不是打开Allow
Arbitrary
Loads全部放开,设置信息如下:





Xcode的Info.plist中NSAppTransportSecurity设置
复制代码


  1. <key>NSAppTransportSecurity</key>
  2. <dict>
  3. <key>NSExceptionDomains</key>
  4. <dict>
  5. <key>tv.diveinedu.com</key>
  6. <dict>
  7. <key>NSExceptionAllowsInsecureHTTPLoads</key>
  8. <true/>
  9. </dict>
  10. </dict>
  11. </dict>
复制代码




  1. NSAllowsArbitraryLoads
  2. true
复制代码

除此之外,要做到严格验证防止像Charles那样的中心人代理抓包,AFNetworking代码应该用如下设置:


  1. //服务器端配置的包罗公钥的证书分发到客户端后,需要转换为DER格式的证书文件.
  2. //openssl
  3. x509
  4. -outform
  5. der
  6. -in
  7. tv.diveinedu.com.crt
  8. -out
  9. tv.diveinedu.com.der
  10. NSString
  11. *certFilePath
  12. =
  13. [[NSBundle
  14. mainBundle]
  15. pathForResource:@"tv.diveinedu.com"
  16. ofType:@"der"];
  17. NSData
  18. *certData
  19. =
  20. [NSData
  21. dataWithContentsOfFile:certFilePath];
  22. NSSet
  23. *certSet
  24. =
  25. [NSSet
  26. setWithObject:certData];
  27. AFSecurityPolicy
  28. *policy
  29. =
  30. [AFSecurityPolicy
  31. policyWithPinningMode:AFSSLPinningModePublicKey
  32. withPinnedCertificates:certSet];
  33. policy.allowInvalidCertificates
  34. =
  35. YES;
  36. AFHTTPSessionManager
  37. *manager
  38. =
  39. [AFHTTPSessionManager
  40. manager];
  41. manager.securityPolicy
  42. =
  43. policy;
  44. //关闭缓存避免干扰测试
  45. manager.requestSerializer.cachePolicy
  46. =
  47. NSURLRequestReloadIgnoringLocalCacheData;
  48. [manager
  49. GET:@"https://tv.diveinedu.com/channel/"
  50. parameters:nil
  51. progress:nil
  52. success:^(NSURLSessionDataTask
  53. *
  54. _Nonnull
  55. task,
  56. id
  57. _Nullable
  58. responseObject)
  59. {
  60. NSLog(@"%@",responseObject);
  61. }
  62. failure:^(NSURLSessionDataTask
  63. *
  64. _Nullable
  65. task,
  66. NSError
  67. *
  68. _Nonnull
  69. error)
  70. {
  71. NSLog(@"%@",error);
  72. }];
复制代码



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

当使用Charles
SSL代理时Xcode调试终端出错信息图:





Xcode调试终端出错信息

代理服务器Charles那边的出错信息图:





Charles那边的出错信息
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表