AFNetworking框架分析(六)——AFSecurityP
在AF框架中,AFSecurityPolicy类只做了一件事,就是完成HTTPS认证。作为单向认证证书是否合法。
先来看看HTTP协议,超文本传输协议。目前使用最广泛的HTTP协议版本为1.1。在请求报文中,使用持久连接connection:keep-alive,默认不关闭连接,可以被多个请求复用。使用管道机制,复用一个tcp可以发送多个请求,但同时带来的问题客户端同时发送多个请求之后,服务端的响应只能是依次执行。
在HTTP2.0版本中,首先解决1.1版本中存在的问题,服务端的响应不再依次执行。所有HTTP2.0 通信都在一个TCP连接上完成, 这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一或多个帧组成, 这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。也就是多工功能。
其次是2.0协议对请求头部内容的压缩。HTTP 1.x每一次通信(请求/响应)都会携带首部信息用于描述资源属性。HTTP 2.0在客户端和服务端之间使用“首部表”来跟踪和存储之前发送的键-值对。首部表在连接过程中始终存在,新增的键-值对会更新到表尾,因此,不需要每次通信都需要再携带首部。
第三,HTTP2.0协议中可以实现服务端自推送功能。服务端可以根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。
HTTP2.0原理参考文章连接
HTTP的缺点也很明显。明文传输,内容会被窃听;而且没有验证通信方的身份,就会遭遇信息伪装;无法验证报文的完整性,就可能会遇到中间人攻击遭遇信息的篡改。这时,就需要使用HTTPS协议来弥补HTTP协议中的缺陷。
在HTTPS协议中,首先对通讯进行加密,建议安全的通信线路,同时还会提供SSL证书确保通讯内容安全。
HTTPS协议包含了HTTP协议、SSL加密、证书认证以及完整性保护。
SSL证书分为两种:CA证书(certificate authority),受信任的;自签证书,不受信任。
HTTPS协议中的加密是用共享密钥加密与公开密钥加密的混合加密。共享密钥加密,加解密使用同一个密钥,即对称加密;公开密钥加密,分为公钥与私钥,公钥加密公开使用,而私钥则用于解密。HTTPS协议在交换密钥时使用公开密钥加密,在通信报文交换的过程中使用共享密钥。首先使用公开密钥加密的方式安全地交换将在稍后的共享密钥加密中要使用的密钥,在确保交换的密钥时安全的前提下,再使用共享密钥加密方式进行通讯交互。
既然AFSecurityPolicy类是用单向认证,使用一张图来更直观地表示交互过程。
HTTPS协议在保证通讯安全的同时,也带来了一些问题:通讯交互处理会变慢,通信时间变长,消耗额外的CPU与内存等资源。
有了关于HTTPS协议的基本介绍,这时再回来看看AF框架中AFSecurityPolicy类如何配置以及作用。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy = [self customPolicy];
-(AFSecurityPolicy *)customPolicy
{
//加载本地的public.cer证书文件
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"public" ofType:@"cer"];
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
NSSet *set = [NSSet setWithObject:cerData];
//初始化AFSecurityPolicy,导入证书文件
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:set];
//是否允许使用无效的证书,默认为NO
policy.allowInvalidCertificates = YES;
//是否验证证书中的域名domain,可能访问其子域名
policy.validatesDomainName = NO;
return policy;
}
在初始化AFSecurityPolicy对象时,方法中包含一个AFSSLPinningMode枚举
AFSSLPinningMode枚举中的作用
查看其初始化方法实现的内部
// 根据SSL验证模式和指定的证书集合创建实例
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates {
AFSecurityPolicy *securityPolicy = [[self alloc] init];
securityPolicy.SSLPinningMode = pinningMode;
// 设置证书集合 如果是默认的 已经通过[self defaultPinnedCertificates]得到了
[securityPolicy setPinnedCertificates:pinnedCertificates];
return securityPolicy;
}
通过HTTPS协议收到服务端的challenge时,比如需要验证证书,会执行- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
代理方法
在AF框架中,遵循挑战处理的代理方法时,自定义了用来如何应对服务器端的不同类型认证挑战。首先判断了接受服务器挑战的方法是否是信任证书,其中只需要验证服务端证书是否安全(即https的单向认证,这是AF默认处理的认证方式,其他的认证方式,只能由自定义Block的实现)。当信任评估通过后,将信任凭证回调给服务器,之后即可进行数据通讯。 收到服务端挑战的代理方法实现