UINavigationController

驗證證書的API(相關API在Security Framework中):
驗證流程:
1.獲取須要驗證信任的對象(Trust Object,證書發佈機構),不一樣的應用場景下獲取的方式都不同,對於NSURLConnection來講,是從:
delegate回調方法:-connection:willSendRequestForAuthenticationChallenge:
的參數challenge中獲取:
[challenge.protectionSpace serverTrust]
2.使用系統默認驗證方式驗證Trust Object(這裏會從操做系統的信任列表中尋找對應證書發佈機構的數字證書獲取公鑰對Trust Object證書發佈機構進行驗證)
3.驗證經過2後,通常的安全要求下:
使用Trust Object生成一份憑證[NSURLCredential credentialForTrust:serverTrust],
傳入challenge的sender中[challenge.sender useCredential:cred forAuthenticationChallenge:challenge]處理,創建鏈接。
4. 假若有更強的安全要求:
能夠繼續對Trust Object進行更嚴格的驗證。經常使用的方式是在本地導入證書,驗證Trust Object與導入的證書是否匹配。
5. 假如驗證失敗:
取消這次Challenge-Response Authentication驗證流程,拒絕鏈接請求。
/*
假如是自建證書的,則不使用第二步系統默認的驗證方式,由於自建證書的根CA的數字簽名未在操做系統的信任列表中。
*/
示範例子:
使用NSURLConnection支持HTTPS的實現:
//start the connection
NSURL *httpsURL=[NSURL URLWithString:@"https://www.google.com"];
self.connection=[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:httpsURL]delegate:self];
//delegate functions
-(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使用這個憑證來繼續鏈接
NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}else{
//5)驗證失敗,取消此次驗證流程
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
/*
上面是代碼是經過系統默認驗證流程來驗證證書的(就是系統去系統本地信任列表中尋找數字證書驗證證書發佈機構,所以上面收到的驗證對象必須是正規的證書發佈機構)
假如咱們鏈接地址返回的是自建證書,直接使用SecTrustEvaluate進行驗證是不會成功的。
又或者
即便服務器返回的證書是信任CA簽發的,又如何肯定這證書就是咱們想要的特定證書?
這就須要先在本地導入證書,設置成須要參與驗證的Anchor Certificate(錨點證書,經過SecTrustSetAnchorCertificates設置了參與校驗錨點證書以後,假如驗證的數字證書是這個錨點證書的子節點,即驗證的數字證書是由錨點證書對應CA或子CA簽發的,或是該證書自己,則信任該證書),
再調用SecTrustEvaluate來驗證
示範例子(對上面的例子修改):
//先導入證書
NSString * cerPath = ...; //證書的路徑
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設置的證書或者系統默認提供的證書,對trust進行驗證
OSStatus status=SecTrustEvaluate(trust,&result);
if(status==errSecSuccess && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)){
//3.驗證成功,生成NSURLCredential憑證cred,告知challenge的sender使用這個憑證來繼續鏈接
NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}else{
//5)驗證失敗,取消此次驗證流程
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
建議採用本地導入證書的方式驗證證書,來保證足夠的安全性。
*/

安全

相關文章
相關標籤/搜索