您的位置:首页 > 理论基础 > 计算机网络

iOS客户端校验https网络请求证书

2016-10-20 10:37 429 查看
其实iOS系统的网络请求都有校验,比如NSURLConnection、NSURLSession都有系统的自动校验。具体的校验可进行百度

我使用的是NSURLConnection进行的网络请求,NSURLConnection是代理回调的请求方式,其中有两个代理方法是用于进行校验证书的

另外我说一下我们的需求,我们要求使用指定的CA证书进行校验不能使用系统的校验,系统的校验可自行百度,他校验证书的信任列表。但是如果我使用fiddler 进行抓取https,让fiddler自己生成一个自签名的证书,然后把这个证书装到客户端信任列表,那么fiddler就能获取https请求数据,因为系统的校验证书是可以校验通过的,所以我们要禁止这种截获数据,因此有了自定义校验证书

好了 不多说了 上代码

//https 证书验证
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)prote {
///NO 系统进行管理  YES 调用connection: didReceiveAuthenticationChallenge 进行验证
return YES;
}
//手动验证 https 证书
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
// 获取der格式CA证书路径
NSString *certPath = [[NSBundle mainBundle] pathForResource:@"CustomCA" ofType:@"der"];
// 提取二进制内容
NSData *derCA = [NSData dataWithContentsOfFile:certPath];

// 根据二进制内容提取证书信息
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)derCA);
// 形成钥匙链
NSArray * chain = [NSArray arrayWithObject:(__bridge id)(caRef)];

CFArrayRef caChainArrayRef = CFBridgingRetain(chain);

// 取出服务器证书
SecTrustRef trust = [[challenge protectionSpace] serverTrust];

SecTrustResultType trustResult = kSecTrustResultInvalid;
// 设置为我们自有的CA证书钥匙连
int err = SecTrustSetAnchorCertificates(trust, caChainArrayRef);
if (err == noErr) {
// 用CA证书验证服务器证书
err = SecTrustEvaluate(trust, &trustResult);
}
// 检查结果 kSecTrustResultConfirm 当值是这个时应询问用户许可,但这个值在iOS7.0后废弃了,系统支持到7.0 可以不管理这个值
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));

#warning 使用根证书验证存在服务器证书如果不是我们使用的GlobalSignRootCA签发的这个子证书签发的(另一个子证书签发)也能校验过
if (trusted) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else {
//验证证书不通过
//当执行到这的时候应该去排查一下具体为什么没过,可以看一下是否换证书了,是否是用GlobalSignRootCA或其直接签发的子证书签发的
//现在的验证的全部是这个机构签发的证书。这个机构换证书的几率很小,因为验证书是用根证书验的,签发机构要换 就要把所有证书换掉 一般不会这么做,
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
做到这就可以了这就进行了自定义验证https证书,将customCA.der换成你自己的证书,至于证书如何得到,你可以去你们的网站道出,如果你还有什么不会的可以随时找我

我的猜想:我没试过fiddler能不能把证书换成自定义的,如果说可以的话,那上面的操作意义不大
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息