由于蘋果規定2017年1月1日以后,所有APP都要使用HTTPS進行網絡請求,否則無法上架,因此研究了一下在iOS中使用HTTPS請求的實現。相信大家對HTTPS都或多或少有些了解,這里我就不再介紹了,主要功能就是將傳輸的報文進行加密,提高安全性。
一、簡介
- HTTPS
即 HTTP + SSL 層,具體介紹在這里。 - 關于 iOS HTTPS 應該是大多數人想要的
二、HTTPS與HTTP的區別
-
這里用兩張圖來介紹兩者的區別:
HTTP:當客戶端發送請求,那么服務器會直接返回數據。
HTTP
HTTPS:當客戶端第一次發送請求的時候,服務器會返回一個包含公鑰的受保護空間(也成為證書),當我們發送請求的時候,公鑰會將請求加密再發送給服務器,服務器接到請求之后,用自帶的私鑰進行解密,如果正確再返回數據。這就是 HTTPS 的安全性所在。
HTTPS
三、分類
- 單向認證
- 雙向認證
具體參考http://www.lxweimin.com/p/25efb6d8ec8c
四、證書準備
證書分為兩種,一種是花錢向認證的機構購買的證書,服務端如果使用的是這類證書的話,那一般客戶端不需要做什么,用HTTPS進行請求就行了,蘋果內置了那些受信任的根證書的。另一種是自己制作的證書,使用這類證書的話是不受信任的(當然也不用花錢買),因此需要我們在代碼中將該證書設置為信任證書。
1.證書轉換
在服務器人員,給你發送的crt證書后,進到證書路徑,執行下面語句
openssl x509 -in 你的證書.crt -out你的證書.cer -outform der
這樣你就可以得到cer類型的證書了。雙擊,導入電腦。
2.證書放入工程
(1)、可以直接把轉換好的cer文件拖動到工程中。
(2)、可以在鑰匙串內,找到你導入的證書,單擊右鍵,導出項目,就可以導出.cer文件的證書了
=======修改info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
====AFN 支持https(校驗證書,不可以抓包):
// 1.初始化單例類
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 注意寫法的變化
manager.securityPolicy= [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
AFSSLPinningModeNone 這個模式表示不做 SSL pinning,只跟瀏覽器一樣在系統的信任機構列表里驗證服務端返回的證書。若證書是信任機構簽發的就會通過,若是自己服務器生成的證書,這里是不會通過的。
AFSSLPinningModeCertificate 這個模式表示用證書綁定方式驗證證書,需要客戶端保存有服務端的證書拷貝,這里驗證分兩步,第一步驗證證書的域名/有效期等信息,第二步是對比服務端返回的證書跟客戶端返回的是否一致。
AFSSLPinningModePublicKey 這個模式同樣是用證書綁定方式驗證,客戶端要有服務端的證書拷貝,只是驗證時只驗證證書里的公鑰,不驗證證書的有效期等信息。只要公鑰是正確的,就能保證通信不會被竊聽,因為中間人沒有私鑰,無法解開通過公鑰加密的數據。
// 2.設置證書模式
NSString * cerPath = [[NSBundlemainBundle]pathForResource:@"xxx"ofType:@"cer"];
NSData * cerData = [NSDatadataWithContentsOfFile:cerPath];
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:cerData,nil]];
// 客戶端是否信任非法證書
manager.securityPolicy.allowInvalidCertificates = YES;
// 是否在證書域字段中驗證域名
[manager.securityPolicy setValidatesDomainName:NO];
=====AFN 支持https(不校驗證書,可以抓包查看):
// 1.初始化單例類
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 2.設置非校驗證書模式
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
manager.securityPolicy.allowInvalidCertificates = YES;
[manager.securityPolicy setValidatesDomainName:NO];