在經過了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>