引用自 http://www.cnblogs.com/jys509/p/5001566.htmlcss
通常来说若是app用了web service , 咱们须要防止数据嗅探来保证数据安全.一般的作法是用ssl来链接以防止数据抓包和嗅探html
其实这么作的话仍是不够的 。 咱们还须要防止中间人攻击(不明白的本身去百度)。攻击者经过伪造的ssl证书使app链接到了假装的假冒的服务器上,这是个严重的问题!那么如何防止中间人攻击呢?git
首先web服务器必须提供一个ssl证书,须要一个 .crt 文件,而后设置app只能链接有效ssl证书的服务器。web
在开始写代码前,先要把 .crt 文件转成 .cer 文件,而后在加到xcode 里面shell
可使用openssl 进行转换后端
openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
使用AFNetworking 对数据进行只须要两步xcode
第一步:新增一个类安全
+ (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/