1.ATS
1)iOS9中新增App Transport Security(簡(jiǎn)稱ATS)特性, 讓原來(lái)請(qǐng)求時(shí)候用到的HTTP柔吼,全部都轉(zhuǎn)向TLS1.2協(xié)議進(jìn)行傳輸荡陷,也就意味著所有的HTTP協(xié)議都強(qiáng)制使用了HTTPS協(xié)議進(jìn)行傳輸闷供。
- ATS默認(rèn)的條件
服務(wù)器TLS版本至少是1.2版本
連接加密只允許幾種先進(jìn)的加密
證書必須使用SHA256或者更好的哈希算法進(jìn)行簽名氓辣,要么是2048位或者更長(zhǎng)的RSA密鑰低剔,要么就是256位或更長(zhǎng)的ECC密鑰薛夜。
-
3)在iOS9下直接進(jìn)行HTTP請(qǐng)求如果報(bào)錯(cuò)籍茧,可以通過(guò)以下兩種方法解決
- 修改info.plist繼續(xù)使用以前的設(shè)置,在info.plist中梯澜,添加App Transport Security寞冯,配置了節(jié)點(diǎn)表示告訴系統(tǒng)要走自定義的ATS設(shè)置,然后設(shè)置Allows Arbitrary Loads 為 YES晚伙,設(shè)置YES就是禁用ATS功能
- 所有的請(qǐng)求都基于基于"TLS 1.2"版本協(xié)議吮龄。(該方法需要嚴(yán)格遵守官方的規(guī)定,如選用的加密算法咆疗、證書等)
4)HTTPS簡(jiǎn)介
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer)漓帚,是以安全為目標(biāo)的HTTP通道,簡(jiǎn)單講是HTTP的安全版午磁。在HTTP下加入SSL層尝抖,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL漓踢。
它是一個(gè)URI scheme(抽象標(biāo)識(shí)符體系)牵署,句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸喧半。https:URL表明它使用了HTTP奴迅,但HTTPS存在不同于HTTP的默認(rèn)端口及一個(gè)加密/身份驗(yàn)證層(在HTTP與TCP之間)。
- 主要思想是在不安全的網(wǎng)絡(luò)上創(chuàng)建一安全信道,可在使用適當(dāng)?shù)募用馨头?wù)器證書可被驗(yàn)證且可被信任時(shí)取具,提供保護(hù)
- HTTPS的信任繼承基于預(yù)先安裝在瀏覽器中的證書頒發(fā)機(jī)構(gòu)(如VeriSign脖隶、Microsoft等)(意即“我信任證書頒發(fā)機(jī)構(gòu)告訴我應(yīng)該信任的”)
- 一個(gè)到某網(wǎng)站的HTTPS連接可被信任,如果服務(wù)器搭建自己的https 即采用自認(rèn)證的方式來(lái)建立https信道暇检,這樣一般在客戶端是不被信任的产阱,瀏覽器訪問(wèn)的時(shí)候會(huì)有一個(gè)提示,詢問(wèn)是否繼續(xù)
2.HTTPS與HTTP的區(qū)別:
- https協(xié)議需要到ca申請(qǐng)證書块仆,一般免費(fèi)證書很少构蹬,需要交費(fèi)。
- http是超文本傳輸協(xié)議悔据,信息是明文傳輸庄敛,https 則是具有安全性的ssl加密傳輸協(xié)議。
- http和https使用的是完全不同的連接方式科汗,用的端口也不一樣藻烤,前者是80,后者是443头滔。
- http的連接很簡(jiǎn)單怖亭,是無(wú)狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸坤检、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議兴猩,比http協(xié)議安全。
3.對(duì)開發(fā)的影響
- 3.1 如果是自己使用NSURLSession來(lái)封裝網(wǎng)絡(luò)請(qǐng)求早歇,涉及代碼如下峭跳。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
[task resume];
}
- 3.2如果證書不受信任,用該代理方法安裝證書信任服務(wù)
/*
*只要請(qǐng)求的地址是HTTPS的, 就會(huì)調(diào)用下面這個(gè)代理方法
*我們需要在該方法中告訴系統(tǒng), 是否信任服務(wù)器返回的證書
*Challenge: 質(zhì)詢 包含受保護(hù)的區(qū)域
*protectionSpace : 受保護(hù)區(qū)域
*NSURLAuthenticationMethodServerTrust : 證書的類型 服務(wù)器信任
*/
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
// NSLog(@"didReceiveChallenge %@", challenge.protectionSpace);
// 1.判斷服務(wù)器返回的證書類型, 是否是服務(wù)器信任
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(@"調(diào)用了里面這一層是服務(wù)器信任的證書");
/*
NSURLSessionAuthChallengeUseCredential = 0, 使用證書
NSURLSessionAuthChallengePerformDefaultHandling = 1, 忽略證書(默認(rèn)的處理方式)
NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 忽略書證, 并取消這次請(qǐng)求
NSURLSessionAuthChallengeRejectProtectionSpace = 3, 拒絕當(dāng)前這一次, 下一次再詢問(wèn)
*/
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential , card);
}
}
4.使用AFNetworking
如果證書是通過(guò)權(quán)威的CA機(jī)構(gòu)認(rèn)證過(guò)的,那么什么都不用做缺前,但是有證書,卻不受信任悬襟,在使用AFN中衅码,用到AFSecurityPolicy,需要按照以下代碼操作。
有證書但是不受信任的典型網(wǎng)站就是12306脊岳。
AFSecurityPolicy逝段,內(nèi)部有三個(gè)重要的屬性,如下:
AFSSLPinningMode SSLPinningMode; //該屬性標(biāo)明了AFSecurityPolicy是以何種方式來(lái)驗(yàn)證
BOOL allowInvalidCertificates; //是否允許不信任的證書通過(guò)驗(yàn)證割捅,默認(rèn)為NO
BOOL validatesDomainName; //是否驗(yàn)證主機(jī)名奶躯,默認(rèn)為YES
/*
AFSSLPinningMode 枚舉類型有三個(gè)值:
AFSSLPinningModeNone
AFSSLPinningModePublicKey
AFSSLPinningModeCertificate。
AFSSLPinningModeNone 代表了AFSecurityPolicy不做更嚴(yán)格的驗(yàn)證亿驾,"只要是系統(tǒng)信任的證書"就可以通過(guò)驗(yàn)證受到
allowInvalidCertificates和validatesDomainName的影響嘹黔;
AFSSLPinningModePublicKey 通過(guò)"比較證書當(dāng)中公鑰(PublicKey)部分"來(lái)進(jìn)行驗(yàn)證,通過(guò)SecTrustCopyPublicKey方法獲取
本地證書和服務(wù)器證書莫瞬,然后進(jìn)行比較儡蔓,如果有一個(gè)相同郭蕉,則通過(guò)驗(yàn)證,此方式主要適用于自建證書
搭建的HTTPS服務(wù)器和需要較高安全要求的驗(yàn)證喂江;
AFSSLPinningModeCertificate 直接將本地的證書設(shè)置為信任的根證書召锈,然后來(lái)進(jìn)行判斷,并且比較本地證書的內(nèi)容和服務(wù)器
證書內(nèi)容是否相同获询,來(lái)進(jìn)行二次判斷涨岁,此方式適用于較高安全要求的驗(yàn)證。
*/
- (void)afn
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
//接收無(wú)效的證書 默認(rèn)是NO
policy.allowInvalidCertificates = YES;
//不驗(yàn)證域名,默認(rèn)是YES
policy.validatesDomainName = NO;
manager.securityPolicy = policy;
[manager GET:@"https://kyfw.12306.cn/otn" parameters:nil progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//responseObject 是二進(jìn)制數(shù)據(jù)
// NSLog(@"success----%@", responseObject);
NSLog(@"success----%@", [[NSString alloc]initWithData:responseObject
encoding:NSUTF8StringEncoding]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error----%@", error);
}];
}