iOS Anti Fildder Capture Https Data

Published: 三 18 三月 2015
By 小虎

In cat.

Connect Anti Fiddler Captuer Tags: iOS,Https,SSL,Fiddler,Capture Category: Tech

iOS https内容防止fiddler抓包

昨天老板给提了一个bug

“你的App虽然走了https来防止抓包,但是通过Fiddler还是可以进行中间人攻击,能不能解决?”

老板的需求能不解决=。=,开玩笑了

今天开始找资料

我所有的网络请求都是走的AFNetworking,找到很多AFNetworking使用AFSecurityPolicy来进行证书验证的文档。

HTTP请求的安全连接

这篇文章主要讲导入证书,然后去比较

AFNetworking 2.x 的SSL身份认证

这篇文章也是走的导入公钥进行比对

iOS安全系列之一:HTTPS

这篇文章讲了验证的步骤 1. 验证的信任对象 2. 使用系统默认验证方式验证Trust Object 3. 使用Trust Object生成一份凭证 4. 本地导入证书,验证Trust Object与导入的证书是否匹配 5. 根据结果去continue还是cancel

----- 分割线 ------

看了几篇文章,发现主要是讲证书信息导入到AFSecurityPolicy,然后将设置好的AFSecurityPolicy设置到AFHTTPRequestOperationManager的实例中,然后AFNetworking会自动处理。

但是我的网络框架中没有使用默认的AFHTTPRequestOperationManager来管理,使用的自己的NSOperationQueue来组织的。

后来想想AFNetworking底层也是走的NSURLConnicetion,那就研究一下NSURLConnicetion对Https的处理。

NSURLConnicetion- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge这个方法里。

当然AFNetworking里面的AFHTTPRequestOperation有一个blocksetWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge)

所以,只要NSURLConnicetion里面可以处理https证书就可以了。

----- 分割线 ------

先试试网上的方法

//1)获取trust object
SecTrustRef trust = challenge.protectionSpace.serverTrust;
SecTrustResultType result;

//注意:这里将之前导入的证书设置成下面验证的Trust Object的anchor certificate
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)self.trustedCertificates);

//2)SecTrustEvaluate会查找前面SecTrustSetAnchorCertificates设置的证书或者系统默认提供的证书,对trust进行验证
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == errSecSuccess &&
    (result == kSecTrustResultProceed ||
    result == kSecTrustResultUnspecified)) {

    //3)验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接
    NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
    [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];

} else {

    //5)验证失败,取消这次验证流程
    [challenge.sender cancelAuthenticationChallenge:challenge];

}

结果还是可以用Fiddler来抓包,失败

看来这种方式还是没有成功 =。=

继续

----- 分割线 ------

再尝试内置https公钥来处理,先想办法拿到公钥

找了一下,找到一个链接,这里

    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
    NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
    NSLog(@"Remote Certificate Data Length: %ld",[remoteCertificateData length]);
    NSString * strPath = [NSString stringWithFormat:@"%@/cer.cer", DOCUMENTS_PATH];
    [remoteCertificateData writeToFile:strPath atomically:YES];

这样就将拿到的服务器的公钥写到本地了

然后将这个证书内置到工程里

依然在这个block里面做处理

只要比对这两个证书是否一致就好了

这次是可以了

但是。。。。。。。老板说,咱们的https证书8月份就过期了,到时候公钥就变了,需要更新版本才可以,有没有不内置公钥的办法

好吧,办法总比问题多,继续

----- 分割线 ------

尝试比对传过来的公钥的的CA

找了一下,找到一个链接,这里中的验证证书段落。

    if (_sslCACertificatieData) {
    // 根据二进制内容提取证书信息
    SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)_sslCACertificatieData);
    // 形成钥匙链
    NSArray * chain = [NSArray arrayWithObject:(__bridge id)(caRef)];

    CFTypeRef caChainArrayRef = CFBridgingRetain(chain);

    // 取出服务器证书
    SecTrustRef trust = [[challenge protectionSpace] serverTrust];

    SecTrustResultType trustResult = 0;
    // 设置为我们自有的CA证书钥匙连
    int err = SecTrustSetAnchorCertificates(trust, caChainArrayRef);
    if (err == noErr) {
        // 用CA证书验证服务器证书
        err = SecTrustEvaluate(trust, &trustResult);
    }
    // 检查结果
    BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));

    if (trusted) {
        //3)验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接
        NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
        [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
    }
    else
    {
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }

这次试了一下,也可以防止别人使用Fiddler抓包

但是。。。。。老板说,是比内置公钥好多了,只要到时候不更换https证书的厂家的话,ca的有效期还是比较长的,能不能不内置CA,使用系统内置的CA来判断呢?

好吧,想着办法总比问题多,继续搞

加载CA的又一篇文章

Pinning Your SSL Certs

----- 分割线 ------

那只能看看能不能读取出来公钥x509里面的信息来做判断了

找了下,说可以加openssl的框架来验证x509证书

看了几篇文档

How to verify a X509 certificate in C

SecCertificateRef: How to get the certificate information?

iOS: Verifying a File With a Certificate and Signature - Public Key is Wrong, Verification Fails

iphone development: verify the certificate information from a https url

Openssl 对x509证书有效性进行验证

暂时先用内嵌ca证书来解决对服务器x509证书的校验吧。

Comments !

blogroll

social