SSL pinning在构建一个高度安全的移动APP上扮演了一个十分重要的角色。然而如今好多用户在使用无线移动设备去访问无数不安全的无线网络。

  这篇文章主要覆盖了SSL pinning 技术,来帮助我们处理最常见的安全攻击--中间人攻击(MITM)。

  SSL(Secure Socket Layer 安全套接字层)确保客户端-服务器在HTTP请求的方式上将通讯内容加密----被指定为HTTPS(SSL上的HTTP)。这种加密体系是基于PKI(Pbulic Key Infrastructure,公钥体系)和(Session key,会话key)。其中Session key 被引进的原因是对于公钥/私钥的加密和解密会消耗处理能力,会是整个交流进程速度变慢。

  SSL 安全---鉴定

  SSL安全是基于证书的信任链。当一个通信开始的时候,客户端检查服务器的SSL证书,检查这个证书是否被信用根CA机构或者其他用户信任结构所信任。

  尽管SSL通信被认为是一个非常安全的和坚不可摧的,但是中间人攻击依然还是真实存在的威胁,它可以用好几种方法去实现,例如ARP 缓存中毒、DNS 欺骗等。

  对于ARP缓存中毒,可以简单理解为中间人通过地址解析协议的IP映射到设备的Mac地址这一特性进行攻击。例如,我们用一下三个角色来描述一个简单的网络:

  一个普通的用户设备U

  攻击者的设备A

  路由器R

  攻击者的设备A可以发送一个ARP依赖包给用户设备U,把他自己伪装成路由器R。为了完成中间人攻击,A发送另一个ARP依赖给R,告诉路由器它就是U。这样的话,A就成了U和R沟通的中间者,A就可以窃听和拦截信息。IP转发经常被用于攻击者在用户设备和路由器的无缝交流。也就是说通过IP转发,攻击者可以窃取和监听,但是用户和路由器是无感知的。

  DNS欺骗主要在于攻击者破话服务器的域名映射。攻击者尝试强迫DNS去返回一个不正确的地址,而这个地址就是攻击者的计算机地址。

  SSL pinning

  我们使用SSL pinning来确保app通信仅仅发生在指定的服务器上。其中的先决条件就是将目标服务器的SSL证书放到app里面。这个证书被用于会话配置。这里我简单介绍SSL pinning在NSURLSession上的使用。

  当谈到NSURLSession使用SSL pinning有点棘手,因为在AFNetworking中,其本身已经有封装好的类可以使用来进行配置。这里没有办法去设置一组证书来自动取消所有本地证书不匹配的response。我们需要手动执行检查来实现在NSURLSession上的SSL pinning。我们很荣幸的是我们可以用Security's framework C API。

  我们可以先来一个默认会话配置的NSURLSession对象。

NSURLSessionConfiguration *seeConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *session = [NSURLSession sessionWithConfiguration:seeConfig delegate:self delegateQueue:nil];

  NSURLSession使用NSURLSessionTask来发送一个请求,我么使用dataTaskWithURL:completionHandler:方法来进行SSL pinning 测试。发送请求类似于下面这样:

    NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:testURL]];[task resume];

该方法仅仅是返回了一个task对象,然后使用resume方法发送请求,或者说是执行任务。

使SSL pinning在:

URLSession:didReceiveChallenge:completionHandler:delegate

方法中实现。在NSURLSession对象上,我们设置自己为代理来调用方法。

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {//得到远程证书SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);//设置ssl政策来检测主域名NSMutableArray *policies = [NSMutableArray array];[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)challenge.protectionSpace.host)];//验证服务器证书
    SecTrustResultType result;SecTrustEvaluate(serverTrust, &result);BOOL certificateIsValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);//得到本地和远程证书dataNSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));NSString *pathToCer = [[NSBundle mainBundle] pathForResource:@"brhttp" ofType:@"cer"];NSData *localCertificate = [NSData dataWithContentsOfFile:pathToCer];//检查if ([remoteCertificateData isEqualToData:localCertificate] && certificateIsValid) {NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];completionHandler(NSURLSessionAuthChallengeUseCredential,credential);}else {completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,NULL);}
}

在方法的开始,我们使用SecTrustGetCertificateAtIndex来得到服务器的SSL证书数据。然后使用证书评估设置policies。证书使用SecTrustEvaluate评估,然后返回以下几种认证结果类型之一:

typedef uint32_t SecTrustResultType;
enum {kSecTrustResultInvalid = 0,kSecTrustResultProceed = 1,kSecTrustResultConfirm SEC_DEPRECATED_ATTRIBUTE = 2,kSecTrustResultDeny = 3,kSecTrustResultUnspecified = 4,kSecTrustResultRecoverableTrustFailure = 5,kSecTrustResultFatalTrustFailure = 6,kSecTrustResultOtherError = 7
};

如果我们得到kSecTrustResultProceed和kSecTrustResultUnspecified之外的类型结果,我们可以认为证书是无效的(不被信任的)。

  至今为止我们除了检测远程服务器证书评估外,还没有做其他事情,对于SSL pinning 检测我们需要通过SecCertificateRef来得到他的NSData。这个SecCertificateRef来自于challenge.protectionSpace.serverTrust。而本地的NSData来自本地的.cer证书文件。然后我们使用isEqual来进行SSL pinning。

  如果远程服务器证书的NSData等于本地的证书data,那么就可以通过评估,我们可以验证服务器身份然后进行通信,而且还要使用completionHandler(NSURLSessionAuthChallengeUseCredential,credential)执行request。

  然而如果两个data不相等,我们使用completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,NULL)方法来取消dataTask的执行,这样就可以拒绝和服务器沟通。

  这就是在NSURLSession中使用SSL pinning。

 附源码:https://pan.baidu.com/s/1mio6ZnM

转载于:https://www.cnblogs.com/zhanggui/p/5754977.html

如何使用SSL pinning来使你的iOS APP更加安全相关推荐

  1. 手机app抓包https请求信息,解决SSL Pinning验证

    抓包工具: Charles,fiddler,wireshark 其中,前两个用于抓取https请求,wireshark则是包含tcp/udp在内的所有请求,本文中以Charles为例 或者移动端(An ...

  2. Fiddler利用Edxposed框架+TrustMeAlready来突破SSL pinning抓取手机APP数据

    一.背景 在使用fiddler做代理抓取应用数据包时,如果要抓取到HTTPS数据,需要将fiddler证书导入到浏览器或手机. 浏览器或手机设置好fiddler的代理地址,即可抓取到https数据包. ...

  3. 利用Frida绕过Android App(途牛apk)的SSL Pinning

    0x00 前言 做APP测试过程中,使用burp无法抓到数据包或提示网络错误可能是因为APP启用了SSL Pinning,刚好最近接触到途牛apk就是这种情况,于是便有了本文. 0x01 SSL Pi ...

  4. How to bypass Instagram SSL Pinning on Android

    How to bypass Instagram SSL Pinning on Android http://www.ifind.cc/view/115

  5. 抖音SSL Pinning绕过

    问题背景 解决方法 总结 问题背景 用Charles(Mac版)抓包iPhone中的https请求,出现unknown.以前遇到过这种问题,是通过Charles抓包https中出现unknown这篇文 ...

  6. 用frida突破SSL pinning抓包

    python任意版本安装frida,手机端使用的mumu模拟器,其他的也可以 pip install frida adb 连接 mumu模拟器 查看内核 adb shell su cat /proc/ ...

  7. iOS 防止抓包(SSL Pinning)

    1.判断是否有网络代理(不推荐) 当进行网络请求的时候,客户端判断当前是否设置了代理,如果设置了代理,不允许进行访问,附带判断是否设置代理的代码: + (BOOL)getProxyStatus {NS ...

  8. 关于代理抓包,ssl pinning解决方案

    ** 详情见我的博客小生博客 ** 抓包 代理抓包 Fiddler, charles能抓http/https/websocket属于应用层 优点:配置简单,抓取解析ssl方便 缺点:app对代理抓包的 ...

  9. 无感知抓包的几种实现方式,除了ssl pinning,app无法检测

    无感知抓包有什么用? 要分析app的流量需要需要进行抓包,常用的抓包方式就是给手机设置一个代理将流量导到抓包软件.这里给手机设置代理,不管是使用wifi代理还是VPN代理都可以被检测到. 有没有不会被 ...

最新文章

  1. 【前沿技术】Facebook 硬件负责人,带摄像头的智能眼镜将在 10 年内成为常态
  2. 网吧电源和网络布线经验谈(1)
  3. 了解一下MongoDB中的写关注(write concern)
  4. HTML5 新增内容
  5. @Autowired和@Resouce的区别
  6. php 5.3配置,php-5.3.3 说明及配置
  7. 【转载】Callable、FutureTask中阻塞超时返回的坑点
  8. MemSQL初体验 - (3)性能测试
  9. 静态代理和JDK动态代理
  10. ubuntu adb 调试手机
  11. 【最简便解法】1066 图像过滤 (15分)
  12. KindEditor使用过程中,用JQ提交表单时,获取不到编辑器的内容
  13. ip访问次数统计 nginx_Linux分析Nginx日志统计IP访问次数的shell脚本
  14. 判断字符串中是否包含指定字符(JavaScript)
  15. 生活小记--工作一年后的菜鸡
  16. Julia: readcsv 如何处理带中文字符的CSV文件
  17. 短视频运营的目标:引流并转化客户
  18. 揭密Oracle之七种武器之三:破译古老的谜题---共享CBC Latch的秘密
  19. Windows Vista SP1
  20. 视频号6个涨粉方法,运营小技巧

热门文章

  1. sift+图像匹配 算法
  2. pygame中Rect(left, top, width, height)的参数详解
  3. [BUUCTF-pwn]——jarvisoj_level2_x64
  4. Linux查看当前http连接,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  5. php鸡兔同笼试题,数学运算之鸡兔同笼问题
  6. MySQL 命令大全 - 命令详解
  7. c# thread 编程
  8. 使用Spring的NamedParameterJdbcTemplate完成DAO操作
  9. poi jxl 生成EXCEL 报表
  10. Hibernate query by Example