你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> https 平安驗證問題

https 平安驗證問題

編輯:IOS開發綜合

這篇文章為您講述https 平安驗證問題的文章,詳細辦法請看引見

最近為了滿足蘋果的 https 要求, 經過努力終於寫出了辦法

驗證 SSL 證書能否滿足 ATS 要求

nscurl --ats-diagnostics --verbose https://你的域名

PASS 契合要求

輸入滿足 ATS 的證書

openssl s_client -connect 你的域名:443 </dev/null 2>/dev/null | openssl x509 -outform DER > https.cer

1. 針對 A.netWorking (2.6.0之前的版本)

AFSecurityPolicy分三種驗證形式:

AFSSLPinningModeNone

這個形式表示不做SSL pinning,只跟閱讀器一樣在零碎的信任機構列表裡驗證服務端前往的證書。若證書是信任機構簽發的就會經過,若是自己服務器生成的證書就不會經過。

AFSSLPinningModeCertificate

這個形式表示用證書綁定方式驗證證書,需求客戶端保管有服務端的證書拷貝,這裡驗證分兩步,第一步驗證證書的域名無效期等信息,第二步是比照服務端前往的證書跟客戶端前往的能否分歧。

AFSSLPinningModePublicKey

這個形式異樣是用證書綁定方式驗證,客戶端要有服務端的證書拷貝,只是驗證時只驗證證書裡的公鑰,不驗證證書的無效期等信息。只需公鑰是正確的,就能保證通訊不會被竊聽,由於兩頭人沒有私鑰,無法解守舊過公鑰加密的數據。

// 正對是 app 新人的機構發布的 SSL 證書

AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

//alloWinvalidCertificates 能否允許有效證書(也就是自建的證書),默許為NO //假如是需求驗證自建證書,需求設置為YES

securityPolicy.alloWinvalidCertificates = YES;

//validatesDomainName 能否需求驗證域名,默許為YES;

//假設證書的域名與你懇求的域名不分歧,需把該項設置為NO;如設成NO的話,即服務器運用其他可信任機構頒發的證書,也可以樹立銜接,這個十分風險,建議翻開。

//置為NO,次要用於這種狀況:客戶端懇求的是子域名,而證書上的是另外一個域名。由於SSL證書上的域名是獨立的,假設證書上注冊的域名是www.google.com,那麼mail.google.com是無法驗證經過的;當然,有錢可以注冊通配符的域名*.google.com,但這個還是比擬貴的。

//如置為NO,建議自己添加對應域名的校驗邏輯。

securityPolicy.validatesDomainName = YES;

//validatesCertificateChain 能否驗證整個證書鏈,默許為YES

//設置為YES,會將服務器前往的Trust Object上的證書鏈與本地導入的證書停止比照,這就意味著,假設你的證書鏈是這樣的:

//GeoTrust Global CA // Google Inte.net Authority G2

// *.google.com //那麼,除了導入*.google.com之外,還需求導入證書鏈上一切的CA證書(GeoTrust Global CA, Google Inte.net Authority G2);

//如是自建證書的時分,可以設置為YES,加強平安性;假設是信任的CA所簽發的證書,則建議封閉該驗證,由於整個證書鏈逐個比對是完全沒有必要(請檢查源代碼);

securityPolicy.validatesCertificateChain = NO; // 2.6.0之前不需求, 之後需求

requestOperationManager.securityPolicy = securityPolicy;

// 照實自建的證書

還需求把證書導入本地工程中, 並天添加以下代碼

NSData *cerData = [self getSSLCerByCerName:@"本地SSL證書的名字 "]; [securityPolicy setPinnedCertificates:@[cerData]];

// 獲取 SSL 證書

+ (NSData *)getSSLCerByCerName:(NSString *)cerName { NSString *cerPath = [[NSBundle mainBundle] pathForResource:cerName ofType:@"cer"]; NSData *certData = [NSData dataWithContentsOfFile:cerPath]; return certData;}

2. 針對 NSURLConnection

驗證證書的API

相關的Api在Security Framework中,驗證流程如下:

1). 第一步,先獲取需求驗證的信任對象(Trust Object)。這個Trust Object在不同的使用場景下獲取的方式都不一樣,關於NSURLConnection來說,是從delegate辦法-connection:willSendRequestForAuthenticationChallenge:回調回來的參數challenge中獲取([challenge.protectionSpace serverTrust])。

2). 運用零碎默許驗證方式驗證Trust Object。SecTrustEvaLuate會依據Trust Object的驗證戰略,一級一級往上,驗證證書鏈上每一級數字簽名的無效性(上一局部有解說),從而評價證書的無效性。

3). 如第二步驗證經過了,普通的平安要求下,就可以直接驗證經過,進入到下一步:運用Trust Object生成一份憑證([NSURLCredential credentialForTrust:serverTrust]),傳入challenge的sender中([challenge.sender useCredential:cred forAuthenticationChallenge:challenge])處置,樹立銜接。

4). 假設有更強的平安要求,可以持續對Trust Object停止更嚴厲的驗證。常用的方式是在本地導入證書,驗證Trust Object與導入的證書能否婚配。更多的辦法可以檢查Enforcing Stricter Server Trust EvaLuation,這一局部在解說AFNetworking源碼中會解說到。

5). 假設驗證失敗,取消此次Challenge-Response Authentication驗證流程,回絕銜接懇求。

ps: 假設是自建證書的,則不運用第二步零碎默許的驗證方式,由於自建證書的根CA的數字簽名未在操作零碎的信任列表中。

IOS受權驗證的API和流程大約理解了,上面,我們看看在NSURLConnection中的代碼完成:

// NSURLConnection Https 平安驗證問題- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{ return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];}// 針對的是自建證書, 未受平安機構信任- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { static CFArrayRef certs; if (!certs) { NSData*certData =[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"本地工程中的SSL證書的名字" ofType:@"cer"]]; SecCertificateRef rootcert =SecCertificateCreateWithData(kCFAllocatorDefault,CFBridgingRetain(certData)); const void *array[1] = { rootcert }; certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks); CFRelease(rootcert); } SecTrustRef trust = [[challenge protectionSpace] serverTrust]; // 針對一個證書對應多個域名, 無需驗證域名 NSMutableArray *policies = [NSMutableArray array]; // BasicX509 不驗證域名能否相反 SecPolicyRef policy = SecPolicyCreateBasicX509(); [policies addObject:(__bridge_transfer id)policy]; SecTrustSetPolicies(trust, (__bridge CFArrayRef)policies); int err; SecTrustResultType trustResult = 0; err = SecTrustSetAnchorCertificates(trust, certs); if (err == noErr) { err = SecTrustEvaLuate(trust,&trustResult); } CFRelease(trust); // kSecTrustResultUnspecified: 零碎隱式地信任這個證書 // kSecTrustResultProceed: 用戶參加自己的信任錨點,顯式地通知零碎這個證書是值得信任的 BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified)); if (trusted) { [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; }else{ [challenge.sender cancelAuthenticationChallenge:challenge]; }}

// SSL 證書是經過信任的機構受權的, 不必再把證書寄存在本地- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { //1)獲取trust object SecTrustRef trust = challenge.protectionSpace.serverTrust; SecTrustResultType result; // 針對一個證書對應多個域名, 無需驗證域名 NSMutableArray *policies = [NSMutableArray array]; // BasicX509 不驗證域名能否相反 SecPolicyRef policy = SecPolicyCreateBasicX509(); [policies addObject:(__bridge_transfer id)policy]; SecTrustSetPolicies(trust, (__bridge CFArrayRef)policies); //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]; }}

謝謝您的訪問.

【https 平安驗證問題】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved