使用AFNetworking來支持HTTPS
+ (AFSecurityPolicy*)customSecurityPolicy
{
// 先導入證書
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"Robert Laurence.cer" ofType:nil];//證書的路徑
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用證書驗證模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates 是否允許無效證書(也就是自建的證書)祟辟,默認為NO 如果是需要驗證自建證書医瘫,需要設置為YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要驗證域名,默認為YES旧困;
//假如證書的域名與你請求的域名不一致登下,需把該項設置為NO茫孔;如設成NO的話,即服務器使用其他可信任機構頒發(fā)的證書被芳,也可以建立連接缰贝,這個非常危險,建議打開畔濒。
//置為NO剩晴,主要用于這種情況:客戶端請求的是子域名,而證書上的是另外一個域名侵状。因為SSL證書上的域名是獨立的赞弥,假如證書上注冊的域名是www.google.com,那么mail.google.com是無法驗證通過的趣兄;當然绽左,有錢可以注冊通配符的域名*.google.com,但這個還是比較貴的艇潭。
//如置為NO拼窥,建議自己添加對應域名的校驗邏輯。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = @[certData];
return securityPolicy;
}
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 加上這行代碼蹋凝,https ssl 驗證鲁纠。
manager.securityPolicy = [self customSecurityPolicy];
[manager GET:url parameters:params progress:^(NSProgress * downloadProgress) {
} success:^(NSURLSessionDataTask * task, id responseObject) ]{
} failure:^(NSURLSessionDataTask * task, NSError * error) {
}];
使用NSURLConnection支持HTTPS的實現
// 通過系統(tǒng)默認驗證流程來驗證證書
NSURL * httpsURL = [NSURL URLWithString:@"https://www.google.com"];
self.connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:httpsURL] delegate:self];
//回調
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
//1 獲取trust object
SecTrustRef trust = challenge.protectionSpace.serverTrust;
SecTrustResultType result;
//2 SecTrustEvaluate對trust進行驗證
OSStatus status = SecTrustEvaluate(trust, &result);
if(status == errSecSuccess &&(result == kSecTrustResultProceed ||
result == kSecTrustResultUnspecified)) {
//3 驗證成功,生成NSURLCredential憑證cred鳍寂,告知challenge的sender使用這個憑證來繼續(xù)連接
NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}
else
{
//4 驗證失敗改含,取消這次驗證流程
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
// 自建證書
NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"Robert Laurence.cer" ofType:nil]; //證書的路徑
NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(cerData));
self.trustedCertificates = @[CFBridgingRelease(certificate)];
//回調
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
//1 獲取trust object
SecTrustRef trust = challenge.protectionSpace.serverTrust;
SecTrustResultType result;
//注意:這里將之前導入的證書設置成下面驗證的Trust Object的anchor certificate
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)self.trustedCertificates);
//2 SecTrustEvaluate會查找前面SecTrustSetAnchorCertificates設置的證書或者系統(tǒng)默認提供的證書,對trust進行驗證
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == errSecSuccess &&
(result == kSecTrustResultProceed ||
result == kSecTrustResultUnspecified)) {
//3 驗證成功迄汛,生成NSURLCredential憑證cred捍壤,告知challenge的sender使用這個憑證來繼續(xù)連接
NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
} else {
//4 驗證失敗,取消這次驗證流程
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}