• AFNetworking https (引用)


     引用自 http://www.cnblogs.com/jys509/p/5001566.html

    一般来讲如果app用了web service , 我们需要防止数据嗅探来保证数据安全.通常的做法是用ssl来连接以防止数据抓包和嗅探

    其实这么做的话还是不够的 。 我们还需要防止中间人攻击(不明白的自己去百度)。攻击者通过伪造的ssl证书使app连接到了伪装的假冒的服务器上,这是个严重的问题!那么如何防止中间人攻击呢?

    首先web服务器必须提供一个ssl证书,需要一个 .crt 文件,然后设置app只能连接有效ssl证书的服务器。

    在开始写代码前,先要把 .crt 文件转成 .cer 文件,然后在加到xcode 里面

    可以使用openssl 进行转换

    openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der

    使用AFNetworking 对数据进行只需要两步

    第一步:新增一个类

    复制代码
    + (AFSecurityPolicy*)customSecurityPolicy
    {
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"hgcang" ofType:@"cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
    // 如果是需要验证自建证书,需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    //validatesDomainName 是否需要验证域名,默认为YES;
    //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
    //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
    //如置为NO,建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
    securityPolicy.pinnedCertificates = @[certData];
    return securityPolicy;
    }
    复制代码

    第二步:直接在请求方法里加入,只有一行代码

    复制代码
    + (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
    {
    // 1.获得请求管理者
    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    // 2.申明返回的结果是text/html类型
    mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 加上这行代码,https ssl 验证。
    //[mgr setSecurityPolicy:[self customSecurityPolicy]];
    // 3.发送POST请求
    [mgr POST:url parameters:params
    success:^(AFHTTPRequestOperation *operation, id responseObj) {
    if (success) {
    success(responseObj);
    }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    if (failure) {
    failure(error);
    }
    }];
    }
    复制代码


    2 引用:http://my.oschina.net/non6/blog/290175 

    友情提示:本文使用的AFNetworking是最新git pull的2.3.1版本,如果想确认你机器上的AFNetworking版本,请打git tag命令查看。

      绝大部分iOS程序的后台服务都是基于RESTful或者WebService的,不论在任何时候,你都应该将服务置于HTTPS上,因为它可以避免中间人攻击的问题,还自带了基于非对称密钥的加密通道!现实是这些年涌现了大量速成的移动端开发人员,这些人往往基础很差,完全不了解加解密为何物,使用HTTPS后,可以省去教育他们各种加解密技术,生活轻松多了。

      使用HTTPS有个问题,就是CA证书。缺省情况下,iOS要求连接的HTTPS站点必须为CA签名过的合法证书,AFNetworking是个iOS上常用的HTTP访问库,由于它是基于iOS的HTTP网络通讯库,自然证书方面的要求和系统是一致的,也就是你需要有一张合法的站点证书。

      正式的CA证书非常昂贵,很多人都知道,AFNetworking2只要通过下面的代码,你就可以使用自签证书来访问HTTPS

    1
    2
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
        securityPolicy.allowInvalidCertificates = YES;

      这么做有个问题,就是你无法验证证书是否是你的服务器后端的证书,给中间人攻击,即通过重定向路由来分析伪造你的服务器端打开了大门。

      解决方法。AFNetworking2是允许内嵌证书的,通过内嵌证书,AFNetworking2就通过比对服务器端证书、内嵌的证书、站点域名是否一致来验证连接的服务器是否正确。由于CA证书验证是通过站点域名进行验证的,如果你的服务器后端有绑定的域名,这是最方便的。将你的服务器端证书,如果是pem格式的,用下面的命令转成cer格式

    1
    openssl x509 -in <你的服务器证书>.pem -outform der -out server.cer

    然后将生成的server.cer文件,如果有自建ca,再加上ca的cer格式证书,引入到app的bundle里,AFNetworking2在

    1
    2
    3
    4
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
    或者
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
    securityPolicy.allowInvalidCertificates = YES; //还是必须设成YES

    情况下,会自动扫描bundle中.cer的文件,并引入,这样就可以通过自签证书来验证服务器唯一性了。


      我前面说过,验证站点证书,是通过域名的,如果服务器端站点没有绑定域名(万恶的备案),仅靠IP地址上面的方法是绝对不行的。怎么办?答案是想通过设置是不可以的,你只能修改AFNetworking2的源代码!打开AFSecurityPolicy.m文件,找到方法:

    1
    2
    - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                      forDomain:(NSString *)domain

    将下面这部分注释掉

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //            SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
    //
    //            if (!AFServerTrustIsValid(serverTrust)) {
    //                return NO;
    //            }
    //
    //            if (!self.validatesCertificateChain) {
    //                return YES;
    //            }

    这样,AFSecurityPolicy就只会比对服务器证书和内嵌证书是否一致,不会再验证证书是否和站点域名一致了。

      这么做为什么是安全的?了解HTTPS的人都知道,整个验证体系中,最核心的实际上是服务器的私钥。私钥永远,永远也不会离开服务器,或者以任何形式向外传输。私钥和公钥是配对的,如果事先在客户端预留了公钥,只要服务器端的公钥和预留的公钥一致,实际上就已经可以排除中间人攻击了。 

    iOS安全系列之一:HTTPS  :http://oncenote.com/2014/10/21/Security-1-HTTPS/ 

  • 相关阅读:
    tomcat 部署项目的多种方式
    HttpServletRequestWrapper模拟实现分布式Session
    eclipse4.3 解决没有check out as maven project
    Mysql的Merge存储引擎实现分表查询
    ubuntu gcc低版本过低引起错误
    SpringMVC强大的数据绑定
    Reading Notes : 180212 冯诺依曼计算机
    Reading Notes : 180211 概述计算机
    Struts2 第六讲 -- Struts2的结果类型
    Struts2 第五讲 -- Struts2与Servlet的API解耦
  • 原文地址:https://www.cnblogs.com/li-baibo/p/5141301.html
Copyright © 2020-2023  润新知