1.HTTPS传输流程

2.常用加密算法

3.AFN证书校验策略及核心方法

4.SSL Pinning

5.CA证书申请流程


HTTPS经由超文本传输协议进行通信,但利用SSL/TLS来对数据包进行加密。HTTPS开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性

1.HTTPS传输流程

 
HTTPS传输流程.png

由于不相信服务器生成的随机数,所以需要客户端生成pre-master-securet,然后再由服务端加密,最后得到master-securet(主密钥),建立密道通信。(减少被猜中的可能)

2.常用加密算法

非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,RC4,3DES
HASH算法:MD5,SHA1,SHA256

非对称加密算法用于握手过程中的加密生成的密码,
对称加密算法用于对真正传输的数据进行加密,
HASH算法用于验证数据的完整性,是否被篡改等

非对称加密生成密码是整个加密过程的关键,非对称加密会生成公钥和私钥,
公钥负责数据加密,(可以随意传输)
私钥负责解密,(重中之重)

3.AFN证书校验策略及核心方法

NSURLSession 封装了HTTPS链接的建立加密解密功能,但并没有验证证书的合法性,无法避免中间人攻击,要真正的安全通讯,需要我们手动去验证证书,

客户端校验策略

 sessionManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];  

 * AFSSLPinningModeNone 不做SSL pinning 只信任证书颁发机构证书,自己生成证书不通过
* AFSSLPinningModeCertificate 客户端保存证书拷贝 第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
* AFSSLPinningModePublicKey 客户端保存证书拷贝 只是验证时只验证证书里的公钥,不验证证书的有效期等信息

核心证书校验方法

- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain
{ **** AFSSLPinningModeNone 不做SSL Pinning 当需要使用证书验证域名时,需要使用AFSSLPinningModePublicKey或AFSSLPinningModeCertificate if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) { // According to the docs, you should only trust your provided certs for evaluation.
Pinned certificates are added to the trust. Without pinned certificates,
there is nothing to evaluate against. From Apple Docs:
"Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors).
Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");
return NO;
} NSMutableArray *policies = [NSMutableArray array];
**** 需要验证域名时,添加一个域名验证策略
if (self.validatesDomainName) {
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
} else {
[policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
}
**** 设置验证策略
SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); if (self.SSLPinningMode == AFSSLPinningModeNone) {
**** AFSSLPinningModeNone 时,allowInvalidCertificates为YES ,则代表服务器任何证书都能验证
**** 如果是NO,则需要判断此服务器是否是系统信任证书 return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
} else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { **** 如果服务器证书不是系统信任证书,且不允许不信任证书通过验证则返回NO
return NO;
} switch (self.SSLPinningMode) {
case AFSSLPinningModeNone:
default:
return NO;
case AFSSLPinningModeCertificate: { **** AFSSLPinningModeCertificate 是直接将本地证书设置为信任的根证书,然后来进行判断,并且比较本地证书内容和服务器证书内容是否一致,如果有一个相同则返回YES NSMutableArray *pinnedCertificates = [NSMutableArray array];
for (NSData *certificateData in self.pinnedCertificates) {
[pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
} **** 设置本地证书为根证书
SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); **** 通过本地证书来判断服务器证书是否可信,不可信则不通过
if (!AFServerTrustIsValid(serverTrust)) {
return NO;
} // obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
**** 判断本地证书和服务器证书是否相同
for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
return YES;
}
} return NO;
}
case AFSSLPinningModePublicKey: {
NSUInteger trustedPublicKeyCount = 0;
NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);
**** AFSSLPinningModePublicKey 是通过比较证书中公钥部分来进行校验。通过SecTrustCopyPublicKey方法获取本地证书和服务器证书,进行比较,如果有一个相同则验证通过 for (id trustChainPublicKey in publicKeys) {
for (id pinnedPublicKey in self.pinnedPublicKeys) {
if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) {
trustedPublicKeyCount += 1;
}
}
}
return trustedPublicKeyCount > 0;
}
}
return NO;
}

4.SSL Pinning

SSL Pinning
SSL Pinning 即证书绑定,客户端直接保存服务端证书,建立HTTPS连接时会校验服务端返回证书和客户端证书是否一致,一致则不再去信任证书机构里验证。

SSL Pinning 为什么安全

其实如果中间人从客户端取出证书(公钥),并使用证书冒充服务器与客户端进行通信时,也可以通过证书验证,但后续流程走不下去,因为客户端会用公钥加密,中间人从客户端截取的证书是公钥,缺少对应私钥即使截获了信息也无法解密。所以能够最大程度保护信息安全

PS: 从上面的通信过程中,最重要的是存储在服务器的私钥。因为只有私钥生成了在通信过程中传递的证书(公钥),且只有通过私钥才能对公钥加密的信息进行解密,所以在开发过程中保护好私钥的安全。

什么时候使用SSL Pinning

如果证书是从受信任的CA机构颁布的,验证是没有问题的,如果是自己颁发证书,无法通过系统受信任的CA机构列表验证证书时,需要通过SSL Pinnig的方式来验证

如何使用SSL Pinning

1.将.cer 证书放进工程中
2.设置securityPolicy证书校验策略

 #pragma mark - SecurityPolicy
+ (void)securityPolicy:(AFHTTPSessionManager *)sessionManager{ sessionManager.securityPolicy = [AFSecurityPolicy defaultPolicy];
sessionManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
/** allowInvalidCertificates 是否允许不信任的证书(证书无效、证书时间过期)通过验证 ,默认为NO */
[sessionManager.securityPolicy setAllowInvalidCertificates:NO]; /** validatesDomainName 是否验证域名证书的CN(common name)字段 默认YES*/
sessionManager.securityPolicy.validatesDomainName = YES; /** NSSet<NSData*> *pinnedCertificates 根据验证模式来返回用于验证服务器的证书。*/
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"XXXX" ofType:@"cer"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
[sessionManager.securityPolicy setPinnedCertificates:[NSSet setWithArray:@[certData]]]; }
iOS设备已有哪些CA证书

每个版本的iOS设备中,都会包含一些既有的CA根证书。如果接收到的证书是iOS信任的CA根证书签名的,那么则为合法证书;否则则为“非法”证书
iOS已有的CA根证书:https://support.apple.com/en-us/HT204132


作者:StarkShen
链接:http://www.jianshu.com/p/309d5359d5cb
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

iOS安全策略之HTTPS的更多相关文章

  1. ios 中使用https的知识

    先看文章,这篇文章说的是使用AFNetworing进行https时的事项,十分好!http://blog.cnbang.net/tech/2416/ ios中使用https,主要就是使用NSURLCr ...

  2. IOS 采用https 协议访问接口

    申请好证书后,发现ios 仍无法使用https协议访问到数据,发现ios 需要ssl 支持 TLS1.2 . 更改nginx 配置: ssl_protocols TLSv1 TLSv1. TLSv1. ...

  3. 微信H5页面嵌入百度地图---解决手机的webKit定位,ios系统对非https网站不提供支持问题

    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=yGQt ...

  4. iOS app 支持HTTPS iOS开发者相关

    2016年12月21日更新开发者中心链接https://developer.apple.com/news/?id=12212016b该链接是苹果昨天刚在官网给的正式回复 如下: App Transpo ...

  5. Charles抓包(iOS的http/https请求)

    Charles抓包(iOS的http/https请求) Charles安装 HTTP抓包 HTTPS抓包 1. Charles安装 官网下载安装Charles:https://www.charlesp ...

  6. iOS + Nodejs SSL/Https双向认证

    移动互联网的大力发展,安全越来越重要. 什么是双向认证呢?双向认证就是client要验证server的合法性,同一时候server也要验证client的合法性. 这样两方都相互验证,提高安全性. 关于 ...

  7. 使用Fiddler 对ios 设备进行HTTPS 的抓取

    http://blog.csdn.net/skylin19840101/article/details/43485911  使用Fiddler 对ios 设备进行HTTPS 的抓取

  8. iOS ASIHTTPRequest用https协议加密请求

    iOS 终端请求服务端数据时,为了保证数据安全,我们一般会使用https协议加密,而对于iOS的网络编程,我们一般会使用开源框架:ASIHTTPRequest,但是如果使用传统的http方式,即使忽略 ...

  9. iOS ASIHTTPRequest 请求https

    iOS 终端请求服务端数据时,为了保证数据安全,我们一般会使用https协议加密,而对于iOS的网络编程,我们一般会使用开源框架:ASIHTTPRequest,但是如果使用传统的http方式,即使忽略 ...

随机推荐

  1. Groovy简单再入门

    以前试过,忘得差不多了,趁这次从JAVA一直撸到SERVLET,SPRING,GROOVY,GRAILS的机会,再弄一次吧... def authors = [ "Peter Ledbroo ...

  2. JAVA 大数据

  3. MVC.Net:WebAPI添加对jsonP的支持

    在某些情况下,我们需要在WebAPI项目中添加对jsonP的支持.比如我们同时创建了MVC.Net和WebAPI两个项目,这两个项目使用不同的端口,这时如果MVC.Net项目的前端想要直接访问WebA ...

  4. HDU--1054--Strategic Game【最小点覆盖】

    链接:pid=1054">http://acm.hdu.edu.cn/showproblem.php?pid=1054 题意:一个熊孩子玩策略游戏,他须要用最少的士兵守卫最多的道路.假 ...

  5. Android ORMLite ForeignCollection关联外部集合

     <Android ORMLite ForeignCollection关联外部集合>    Android ORMLite ForeignCollection关联外部集合的功能,适合层 ...

  6. Android studio第一次使用配置(三)gradle项目构建

    1.gradle的概念 2.gradle配置jar包.和libs目录导入jar包的差别 3.签名打包: (1)Studio (2)命令行 (3)gradle wrapper的原理 4.BuildCon ...

  7. hibernate实战笔记1---初探

    因为在学习Spring的时候学到有关数据库的章节的时候,提及到了hibernate的集成,可是我对hibernate技术差点儿是一点不了解.仅仅是知道它是一个orm对象映射框架,所以在初探的章节做一下 ...

  8. jQuery事件整理回想

    一.事件 1.载入DOM $(document).ready() 这个第一节里具体介绍了 2.事件绑定 jQuery定义了bind()方法作为统一的接口.用来为每个匹配元素绑定事件处理程序. 其基本的 ...

  9. ubuntu系统启动qtceator时提示:Qt5.5.1/Tools/QtCreator/lib/qtcreator/plugins/libHelp.so: 无法加载库

    在ubuntu系统下安装好qt5.5后启动qtceator时提示:Qt5.5.1/Tools/QtCreator/lib/qtcreator/plugins/libHelp.so: 无法加载库Qt5. ...

  10. P1390--公约数的和

    这个题比较狗,一开始没有啥思路,但是看完题解觉得还是比较好理解的.主要思路就是需要把每个数是几个数的最大公约数求出来,然后求和就行了.蓝书P124例九 设f(n) = gcd(1,n) + gcd(2 ...