我们在发送一个HTTPS请求的时候,到底发生了什么事?用NSURLSession为例这儿梳理下流程:
1. 发送https请求到server (ssl enabled enabled)
2. 收到服务器的认证请求,对于https 来说,也就是一个NSURLAuthenticationChallenge对象,俗称的challenge, 其中这个对象对于client来说有用的信息来源于属性protectionSpace,它是一个NSURLProtectionSpace 对象,里面包括的有用信息有很多: 比如,你访问的domain,server,serverTrust要求的验证方法等。
对HTTPS来说,一般会收到的认证方法为:NSURLAuthenticationMethodServerTrust ,
serverTrust: SecTrustRef 类型,用于对server来的证书的评估,有效则表示信任。
信任后,我们的认证方式就需要提供一个NSCredential ,用信任的serverTrust来创建,然后告诉server说,我信任你了。
对NSURLSession来说,这一切可以在代理方法中完成,举例如下:
- (void)URLSession:(NSURLSession*)session didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDispositiondisposition,NSURLCredential*__nullablecredential))completionHandler {
__blockNSURLCredential*credential =nil;
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
if(credential) {
completionHandler (NSURLSessionAuthChallengeUseCredential,credential);
}
else{
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace,NULL);
}
}
3. AFnetowrking3.0里面对此做了封装,因为它要支持自建cer证书。
a .对于从CA机构来的证书,我们用默认的AFSecurityPolicy 即可
b. 对于自建证书,就得用AFSSLPinningModeCertificate mode,并将cer文件拖入工程中一起打包,开启domain验证,关掉不信任的certification验证(setAllowInvalidCertificates=YES);
PS: 对于CA机构颁发的证书来说,也可以用AFSSLPinningModeCertificate mode,不过要注意别踩坑 。 我踩了二个大坑,1是用OPENSSL命令访问网站得到的证书根本 不能用,2是不能直接将.crt文件 改成.cer文件 使用,就算他们理论上是一样的,还是老实的从keychain里导出cer文件 比较好。
4. AF 验证证书的流程:因为苹果 有一些内嵌的信任证书,比如赛门铁克颁发的,所以就算是我们用默认的pin策略也一样能验证它的正确信,在2.6以后开启的domain验证也能有效的防止中间的攻击。详细 的验证策略可以参考此文章 ,写得比较详细:http://www.cnblogs.com/polobymulberry/p/5174298.html
网友评论