详解IOS如何防止抓包

 更新时间:2021年06月07日 10:32:05   作者:为童沉沦  
为了防止被抓包那么就要了解抓包的原理。本文将详细介绍IOS如何防止抓包,感兴趣的同学,可以参考下。

抓包原理

其实原理很是简单:一般抓包都是通过代理服务来冒充你的服务器,客户端真正交互的是这个假冒的代理服务,这个假冒的服务再和我们真正的服务交互,这个代理就是一个中间者 ,我们所有的数据都会通过这个中间者,所以我们的数据就会被抓取。HTTPS 也同样会被这个中间者伪造的证书来获取我们加密的数据。

防止抓包

为了数据的更安全,那么我们如何来防止被抓包。

第一种思路是:如果我们能判断是否有代理,有代理那么就存在风险。

第二种思路:针对HTTPS 请求。我们判断证书的合法性。

第一种方式的实现:

一、发起请求之前判断是否存在代理,存在代理就直接返回,请求失败。

CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
CFStringRef proxyStr = CFDictionaryGetValue(dicRef, kCFNetworkProxiesHTTPProxy);
NSString *proxy = (__bridge NSString *)(proxyStr);
+ (BOOL)getProxyStatus {
    NSDictionary *proxySettings = NSMakeCollectable([(NSDictionary *)CFNetworkCopySystemProxySettings() autorelease]);
    NSArray *proxies = NSMakeCollectable([(NSArray *)CFNetworkCopyProxiesForURL((CFURLRef)[NSURL URLWithString:@"http://www.baidu.com"], (CFDictionaryRef)proxySettings) autorelease]);
    NSDictionary *settings = [proxies objectAtIndex:0];
    
    NSLog(@"host=%@", [settings objectForKey:(NSString *)kCFProxyHostNameKey]);
    NSLog(@"port=%@", [settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
    NSLog(@"type=%@", [settings objectForKey:(NSString *)kCFProxyTypeKey]);
    
    if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"])
    {
        //没有设置代理
        return NO;
    }
    else
    {
        //设置代理了
        return YES;
    }
}

二、我们可以在请求配置中清空代理,让请求不走代理

我们通过hook到sessionWithConfiguration: 方法。然后清空代理

+ (void)load{
  Method method1 = class_getClassMethod([NSURLSession class],@selector(sessionWithConfiguration:));
  Method method2 = class_getClassMethod([NSURLSession class],@selector(px_sessionWithConfiguration:));
  method_exchangeImplementations(method1, method2);

  Method method3 = class_getClassMethod([NSURLSession class],@selector(sessionWithConfiguration:delegate:delegateQueue:));
  Method method4 = class_getClassMethod([NSURLSession class],@selector(px_sessionWithConfiguration:delegate:delegateQueue:));
  method_exchangeImplementations(method3, method4);
}

+ (NSURLSession*)px_sessionWithConfiguration:(NSURLSessionConfiguration*)configuration delegate:(nullable id)delegate delegateQueue:(nullable NSOperationQueue*)queue
{
      if(configuration) configuration.connectionProxyDictionary = @{};

  return [self px_sessionWithConfiguration:configuration delegate:delegate delegateQueue:queue];
}

+ (NSURLSession*)px_sessionWithConfiguration:(NSURLSessionConfiguration*)configuration
{

      if(configuration) configuration.connectionProxyDictionary = @{};

  return [self px_sessionWithConfiguration:configuration];
}

​ 第二种思路的实现:

主要是针对HTTPS 请求,对证书的一个验证。

通过 SecTrustRef 获取服务端证书的内容

static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) {
   CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust);
   NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount];

   for (CFIndex i = 0; i < certificateCount; i++) {
       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i);
       [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)];
   }

   return [NSArray arrayWithArray:trustChain];
}

然后读取本地证书的内容进行对比

NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
SSet<NSData*> * set = [[NSSet alloc]initWithObjects:certData  , nil];  // 本地证书内容
// 服务端证书内容
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
    if ([set containsObject:trustChainCertificate]) {
        // 证书验证通过
    }
}

SSL Pinning(AFN+SSL Pinning)推荐

SSL Pinning,即SSL证书绑定。通过SSL证书绑定来验证服务器身份,防止应用被抓包。

1、取到证书

客户端需要证书(Certification file), .cer格式的文件。可以跟服务器端索取。

如果他们给个.pem文件,要使用命令行转换:

openssl x509 -inform PEM -in name.pem -outform DER -out name.cer

如果给了个.crt文件,请这样转换:

openssl x509 -in name.crt -out name.cer -outform der

如果啥都不给你,你只能自己动手了:

openssl s_client -connect www.website.com:443 </dev/null 2>/dev/null | openssl x509 -outform DER > myWebsite.cer**

2、把证书加进项目中

把生成的.cer证书文件直接拖到你项目的相关文件夹中,记得勾选Copy items if neede和Add to targets。

3、参数名意思

AFSecurityPolicy

SSLPinningMode

AFSecurityPolicy是AFNetworking中网络通信安全策略模块。它提供三种SSL Pinning Mode

/**

 ## SSL Pinning Modes

 The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.

 enum {

 AFSSLPinningModeNone,

 AFSSLPinningModePublicKey,

 AFSSLPinningModeCertificate,

 }

 `AFSSLPinningModeNone`

 Do not used pinned certificates to validate servers.

 `AFSSLPinningModePublicKey`

 Validate host certificates against public keys of pinned certificates.

 `AFSSLPinningModeCertificate`

 Validate host certificates against pinned certificates.

*/

AFSSLPinningModeNone:完全信任服务器证书;

AFSSLPinningModePublicKey:只比对服务器证书和本地证书的Public Key是否一致,如果一致则信任服务器证书;

AFSSLPinningModeCertificate:比对服务器证书和本地证书的所有内容,完全一致则信任服务器证书;

选择那种模式呢?

AFSSLPinningModeCertificate:最安全的比对模式。但是也比较麻烦,因为证书是打包在APP中,如果服务器证书改变或者到期,旧版本无法使用了,我们就需要用户更新APP来使用最新的证书。

AFSSLPinningModePublicKey:只比对证书的Public Key,只要Public Key没有改变,证书的其他变动都不会影响使用。
如果你不能保证你的用户总是使用你的APP的最新版本,所以我们使用AFSSLPinningModePublicKey。

allowInvalidCertificates

/**
 Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
 */
@property (nonatomic, assign) BOOL allowInvalidCertificates;

是否信任非法证书,默认是NO。

validatesDomainName

/**
 Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
 */
@property (nonatomic, assign) BOOL validatesDomainName;

是否校验证书中DomainName字段,它可能是IP,域名如*.google.com,默认为YES,严格保证安全性。

4、使用AFSecurityPolicy设置SLL Pinning

+ (AFHTTPSessionManager *)manager
{
    static AFHTTPSessionManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        manager =  [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];

        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];
        manager.securityPolicy = securityPolicy;
    });
    return manager;
}

扩展

Android 防止抓包

1、单个接口访问不带代理的

URL url = new URL(urlStr);  
urlConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); 

2、OkHttp框架

OkHttpClient client = new OkHttpClient().newBuilder().proxy(Proxy.NO_PROXY).build(); 

以上就是详解IOS如何防止抓包的详细内容,更多关于IOS如何防止抓包的资料请关注脚本之家其它相关文章!

相关文章

  • iOS实现去除html标签的方法汇总

    iOS实现去除html标签的方法汇总

    相信大家在做网站的时候,经常会遇到去除html标签的问题,下面这篇文章主要给大家总结介绍了关于iOS如何实现去除html标签的一些方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • 分享一个关于Storyboard 跳转与传值

    分享一个关于Storyboard 跳转与传值

    近日不忙,给大家分享一个关于storyboard跳转传值的相关知识,感兴趣的朋友一起看看吧
    2015-12-12
  • iOS App设计模式开发中对interpreter解释器模式的运用

    iOS App设计模式开发中对interpreter解释器模式的运用

    这篇文章主要介绍了iOS App设计模式开发中对interpreter解释器模式的运用,示例为传统的Objective-C写成,需要的朋友可以参考下
    2016-04-04
  • iOS页面跳转及数据传递(三种)

    iOS页面跳转及数据传递(三种)

    本文主要介绍了iOS页面跳转的三种方法及数据传递的方法。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • iOS实现列表与网格两种视图的相互切换

    iOS实现列表与网格两种视图的相互切换

    相信大家应该也都发现了,在现在很多的电商app中,都会有列表视图和网格两种视图的相互切换。例如京东和淘宝。这样更利于提高用户的体验度,所以这篇文章小编就是大家分享下利用iOS实现列表与网格两种视图相互切换的方法,文中介绍的很详细,感兴趣的下面来一起看看吧。
    2016-10-10
  • iOS获取到用户当前位置

    iOS获取到用户当前位置

    这篇文章主要为大家详细介绍了iOS获取到用户当前位置,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 理解iOS多线程应用的开发以及线程的创建方法

    理解iOS多线程应用的开发以及线程的创建方法

    这篇文章主要介绍了理解iOS多线程应用的开发以及线程的创建方法,代码基于传统的Objective-C,需要的朋友可以参考下
    2015-11-11
  • unix 编程进程控制详细介绍

    unix 编程进程控制详细介绍

    这篇文章主要介绍了unix 编程进程控制详细介绍的相关资料,需要的朋友可以参考下
    2017-01-01
  • 关于适配iOS11和iPhoneX的一些事

    关于适配iOS11和iPhoneX的一些事

    随着iOS11和xcode9刚开始正式发布,小编也迫不及待的更新了xcode9,手机也顺利更新到iOS,也终于见到iPhone X 的真面,怎么适配是个问题,下面这篇文章主要给大家介绍了关于适配iOS11和iPhoneX的一些事,需要的朋友可以参考下。
    2017-10-10
  • iOS模仿微信长按识别二维码的多种方式

    iOS模仿微信长按识别二维码的多种方式

    这篇文章主要介绍了iOS模仿微信长按识别二维码的两种方式,文章第二种方式是识别网页中的二维码,具体思路详解大家参考下本文
    2017-07-07

最新评论