美文网首页
AFNetworking里面的HTTPS安全策略实现原理

AFNetworking里面的HTTPS安全策略实现原理

作者: Sweet丶 | 来源:发表于2019-11-06 19:33 被阅读0次

    在使用AFNetworking来作为网络请求库时,对于HTTPS请求的证书验证,我们需要去初始化继承于AFURLSessionManager的AFHTTPSessionManager,设置好securityPolicy, AFURLSessionManager里面有3种安全策略可供使用者选择:

    @interface AFURLSessionManager : NSObject <NSURLSessionDelegate,...>
    @property (nonatomic, strong) AFSecurityPolicy *securityPolicy;
    ...
    @end
    
    @interface AFSecurityPolicy : NSObject <NSSecureCoding, NSCopying>
    @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
    ...
    @end
    
    typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
        AFSSLPinningModeNone,  // 不使用本地证书验证服务器
        AFSSLPinningModePublicKey,  // 使用本地证书里面的公钥验证服务器
        AFSSLPinningModeCertificate,  // 使用本地证书验证服务器
    };
    

    iOS 客户端在发送网络请求时,如果收到服务器的质询(NSURLAuthenticationChallenge)时会调用NSURLSessionDelegate里面的代理方法, AFNetworking安全策略的实现就是在这个方法里面让初始化时设置的securityPolicy去完成的。(NSURLSessionTaskDelegate里面的那个方法原理一样所以这里不讲)

    - (void)URLSession:(NSURLSession *)session
    didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
     completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
    {
        NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        __block NSURLCredential *credential = nil;
    
        if (self.sessionDidReceiveAuthenticationChallenge) {
            disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
        } else {
            if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
                if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                    credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                    if (credential) {
                        disposition = NSURLSessionAuthChallengeUseCredential;
                    } else {
                        disposition = NSURLSessionAuthChallengePerformDefaultHandling;
                    }
                } else {
                    disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
                }
            } else {
                disposition = NSURLSessionAuthChallengePerformDefaultHandling;
            }
        }
    
        if (completionHandler) {
            completionHandler(disposition, credential);
        }
    }
    

    通过源码分析可知其实现原理:
    第一步:在初始化AFHTTPSessionManager时就初始化securityPolicy对象,设置好需要的属性。
    第二步:在需要验证时调用securityPolicy对象方法- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain
    第三步:具体的验证方式,分三种情况进行:

    情况一: AFSSLPinningModeNone,  
    // APP内部没放证书,要验证服务器证书
    返回验证结果是:
    return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
    // 即(允许服务器无效证书) || (不允许无效证书但证书验证通过)为YES ,否则为NO;
    
    
    情况二:AFSSLPinningModeCertificate,   
    // APP内部放了证书,要验证服务器证书,且证书要跟APP内部的证书比对
    第一步:将本地的证书设置为服务器信任`serverTrust`的锚点证书。
     SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
    第二步:对设置了锚点证书的`serverTrust`进行服务器证书验证
    BOOL IsValid = AFServerTrustIsValid(serverTrust);
    第三步:上一步验证通过后,将服务器证书从`serverTrust`获取出来,并与本地证书作比对,比对结果作为返回值。
    NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
    for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
             if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
                        return YES;
               }
      }
    
    情况三:AFSSLPinningModeCertificate,  
     // APP内部放了证书,要验证服务器证书,且要将服务器证书里面的公钥跟APP内部证书的公钥比对
    第一步: 在服务器证书验证通过后,将服务器证书的公钥从`serverTrust`中取出
    NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);
    第二步:本地证书的公钥是在初始化的时候就提取出来了,所以这里直接将本地证书中公钥与publicKeys比对,将结果作为返回值.
    

    相关文章

      网友评论

          本文标题:AFNetworking里面的HTTPS安全策略实现原理

          本文链接:https://www.haomeiwen.com/subject/ldqebctx.html