在经过了ASI,AF,MK统统试验过之后,我尝试了原生的NSURLConnection最终实验成功。记录一下。
首先你需要把服务端的证书不管是crt或者是pem格式的统统转为der格式的,方法如下:
<span style="font-family:Comic Sans MS;font-size:18px;"> openssl x509 -in <你的服务器证书>.crt -outform der -out server.der</span>
把证书添加到项目中,用原生请求https的url然后添加connection的两个代理方法
<span style="font-family:Comic Sans MS;font-size:18px;">- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
} </span><pre name="code" class="objc"><span style="font-family:Comic Sans MS;font-size:18px;">- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{ </span><pre name="code" class="objc"><span style="font-family:Comic Sans MS;font-size:18px;">// 获取der格式CA证书路径
NSString *certPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"der"];
// 提取二进制内容
NSData *derCA = [NSData dataWithContentsOfFile:certPath];
// 根据二进制内容提取证书信息
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)derCA);
// 形成钥匙链
NSArray * chain = [NSArray arrayWithObject:(__bridge id)(caRef)];
caChainArrayRef = CFBridgingRetain(chain);
// 取出服务器证书
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
SecTrustResultType trustResult = 0;
// 设置为我们自有的CA证书钥匙连
int err = SecTrustSetAnchorCertificates(trust, caChainArrayRef);
if (err == noErr) {
// 用CA证书验证服务器证书
err = SecTrustEvaluate(trust, &trustResult);
}
CFRelease(trust);
// 检查结果
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed)||(trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified)); </span>
<span style="font-family:Comic Sans MS;font-size:18px;">if (trusted) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else {
[challenge.sender cancelAuthenticationChallenge:challenge];
}
} </span>