[无限互联]AFNetworking源码之AFSecurityPolicy模块.doc_第1页
[无限互联]AFNetworking源码之AFSecurityPolicy模块.doc_第2页
[无限互联]AFNetworking源码之AFSecurityPolicy模块.doc_第3页
[无限互联]AFNetworking源码之AFSecurityPolicy模块.doc_第4页
[无限互联]AFNetworking源码之AFSecurityPolicy模块.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

续AFNetworking综述,NSURLConnection模块,Serialization模块AFSecurityPolicyNSURLConnection已经封装了https连接的建立、数据的加密解密功能,我们直接使用NSURLConnection是可以访问 https网站的,但NSURLConnection并没有验证证书是否合法,无法避免中间人攻击。要做到真正安全通讯,需要我们手动去验证服务端返回的证书,AFSecurityPolicy封装了证书验证的过程,让用户可以轻易使用,除了去系统信任CA机构列表验证,还支持SSL Pinning方式的验证。AFSecurityPolicy分三种验证模式:AFSSLPinningModeNone这个模式表示不做SSL pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,这里是不会通过的。AFSSLPinningModeCertificate这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。这里还没弄明白第一步的验证是怎么进行的,代码上跟去系统信任机构列表里验证一样调用了SecTrustEvaluate,只是这里的列表换成了客户端保存的那些证书列表。若要验证这个,是否应该把服务端证书的颁发机构根证书也放到客户端里?AFSSLPinningModePublicKey这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。详情请见代码:objcview plaincopy1. #importAFSecurityPolicy.h2. 3. /Equivalentofmacroin,withoutcausingcompilerwarning:4. /DebugAssertisdeprecated:firstdeprecatedinOSX10.85. /这两个宏方法用于方便地处理调用各种证书方法过程中出现的错误,出现错误后用goto语句直接跳转到结束语6. /关于为什么要用_builtin_expect(x,0)而不直接用x!=0,是为了CPU执行时的性能优化,见这里:7. //questions/7346929/why-do-we-use-builtin-expect-when-a-straightforward-way-is-to-use-if-else8. #ifndefAF_Require_noErr9. #defineAF_Require_noErr(errorCode,exceptionLabel)10. do11. if(_builtin_expect(0!=(errorCode),0)12. gotoexceptionLabel;13. 14. while(0)15. #endif16. 17. #if!defined(_IPHONE_OS_VERSION_MIN_REQUIRED)18. staticNSData*AFSecKeyGetData(SecKeyRefkey)19. CFDataRefdata=NULL;20. 21. AF_Require_noErr(SecItemExport(key,kSecFormatUnknown,kSecItemPemArmour,NULL,&data),_out);22. 23. return(_bridge_transferNSData*)data;24. 25. _out:26. if(data)27. CFRelease(data);28. 29. 30. returnnil;31. 32. #endif33. 34. staticBOOLAFSecKeyIsEqualToKey(SecKeyRefkey1,SecKeyRefkey2)35. #ifdefined(_IPHONE_OS_VERSION_MIN_REQUIRED)36. return(_bridgeid)key1isEqual:(_bridgeid)key2;37. #else38. returnAFSecKeyGetData(key1)isEqual:AFSecKeyGetData(key2);39. #endif40. 41. 42. /从证书里取publickey43. staticidAFPublicKeyForCertificate(NSData*certificate)44. idallowedPublicKey=nil;45. 46. /取证书SecCertificateRef-生成证书数组-生成SecTrustRef-从SecTrustRef取PublicKey47. SecCertificateRefallowedCertificate=SecCertificateCreateWithData(NULL,(_bridgeCFDataRef)certificate);48. SecCertificateRefallowedCertificates=allowedCertificate;49. CFArrayReftempCertificates=CFArrayCreate(NULL,(constvoidvoid*)allowedCertificates,1,NULL);50. 51. SecPolicyRefpolicy=SecPolicyCreateBasicX509();52. SecTrustRefallowedTrust;53. AF_Require_noErr(SecTrustCreateWithCertificates(tempCertificates,policy,&allowedTrust),_out);54. 55. SecTrustResultTyperesult;56. AF_Require_noErr(SecTrustEvaluate(allowedTrust,&result),_out);57. 58. allowedPublicKey=(_bridge_transferid)SecTrustCopyPublicKey(allowedTrust);59. 60. _out:61. if(allowedTrust)62. CFRelease(allowedTrust);63. 64. 65. if(policy)66. CFRelease(policy);67. 68. 69. if(tempCertificates)70. CFRelease(tempCertificates);71. 72. 73. if(allowedCertificate)74. CFRelease(allowedCertificate);75. 76. 77. returnallowedPublicKey;78. 79. 80. staticBOOLAFServerTrustIsValid(SecTrustRefserverTrust)81. BOOLisValid=NO;82. SecTrustResultTyperesult;83. AF_Require_noErr(SecTrustEvaluate(serverTrust,&result),_out);84. 85. /kSecTrustResultUnspecified:证书通过验证,但用户没有设置这些证书是否被信任86. /kSecTrustResultProceed:证书通过验证,用户有操作设置了证书被信任,例如在弹出的是否信任的alert框中选择alwaystrust87. isValid=(result=kSecTrustResultUnspecified|result=kSecTrustResultProceed);88. 89. _out:90. returnisValid;91. 92. 93. /取出服务端返回的所有证书94. staticNSArray*AFCertificateTrustChainForServerTrust(SecTrustRefserverTrust)95. CFIndexcertificateCount=SecTrustGetCertificateCount(serverTrust);96. NSMutableArray*trustChain=NSMutableArrayarrayWithCapacity:(NSUInteger)certificateCount;97. 98. for(CFIndexi=0;i生成SecTrustRef-从SecTrustRef取PublicKey112. for(CFIndexi=0;i0)285. publicKeys=publicKeysfirstObject;286. 287. 288. /在本地证书里搜索相等的publickey,记录找到个数289. for(idtrustChainPublicKeyinpublicKeys)290. for(idpinnedPublicKeyinself.pinnedPublicKeys)291. if(AFSecKeyIsEqualToKey(_bridgeSecKeyRef)trustChainPublicKey,(_bridgeSecKeyRef)pinnedPublicKey)292. trustedPublicKeyCount+=1;293. 294. 295. 296. 297. /验证整个证书链的情况:每个publickey都在本地找到算验证通过298. /验证单个证书的情况:找到一个算验证通过299. returntrustedPublicKeyCount0&(self.validatesCertificateChain&trustedPublicKeyCount=serverCertificatescount)|(!self.validatesCertificateChain&trustedPublicKeyCount=1);300. 301. 302. 303. returnNO;304. 305. 306. #pragmamark-NSKeyValueObserving307. 308. +(NSSet*)keyPathsForValuesAffectingPinnedPublicKeys309. returnNSSetsetWithObject:pinnedCertificates;310. 311. 312. endAFNetworkReachabilityManagerAFNetworkReachabilityManager- 这个类监控当前网络的可达性,包括检测域名、广域网和WiFi接口的可达性,提供回调 block 和 notificaiton,在可达性变化时调用。相关代码如下:objcview plaincopy1. /三个初始化网络可达监控器对象的方法2. +(instancetype)sharedManager;3. +(instancetype)managerForDomain:(NSString*)domain;4. +(instancetype)managerForAddress:(conststructsockaddr_in*)address;5. /判断当前网络是否连接6. -(BOOL)isReachable7. returnselfisReachableViaWWAN|selfisReachableViaWiFi;8. 9. /判断当前网络是否连接3G网10. -(BOOL)isReachableViaWWAN11. workReachabilityStatus=AFNetworkReachabilityStatusReachableViaWWAN;12. 13. /判断当前网络是否连接WiFi14. -(BOOL)isReachableViaWiFi15. workReachabilityStatus=AFNetworkReachabilityStatusReachableViaWiFi;16. 17. /开启网络监视器,开始检测网络状态的变化18. -(void)startMonitoring;19. /关闭网络监视器,停止检测网络状态的变化20. -(void)stopMonitoring;21. /网络变化时的回

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论