公司的服務(wù)器被人DDOS攻擊了,后臺(tái)改用自簽證的證書,全部請(qǐng)求改用HTTPS. iOS的網(wǎng)絡(luò)請(qǐng)求也需要全部改. 坑爹的是項(xiàng)目中有兩套請(qǐng)求方案. 1,使用原始蘋果自帶的NSURLConnection 2, 是我接手以后改用的afnetworking. 要全部改的話一下子沒那么多時(shí)間改的過來. 就只好兩個(gè)方案都實(shí)現(xiàn)下HTTPS
- afnetworking 使用字簽證證書訪問HTTPS
- 把服務(wù)器給你的自簽證的證書放入bundle一般是.cer文件
- 創(chuàng)建afnnetworking 安全策略對(duì)象,并設(shè)置發(fā)起請(qǐng)求manager的安全策略屬性.設(shè)置了安全策略屬性,afnnetworking會(huì)自動(dòng)掃描bundl里的證書.
- 最坑的是 iOS9新出的App Transport Security 也就是要我們把所有請(qǐng)求從 HTTP改成HTTPS的家伙, 它竟然不認(rèn)自簽證的證書. 蘋果大爺難道真是土豪慣了,以為我們開發(fā)者都會(huì)買ca的證書嗎. 解決辦法就是那里還是要設(shè)置在Info.plist中添加NSAppTransportSecurity類型Dictionary在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型 Boolean,值設(shè)為YES
//創(chuàng)建安全策略對(duì)象
AFSecurityPolicy * security = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; //設(shè)置證書
security.allowInvalidCertificates = YES; // 由于是自簽證證書 afnnetworking 會(huì)認(rèn)為是無(wú)效的 設(shè)置為允許
security.validatesDomainName = NO; //驗(yàn)證證書綁定的域
[[AFHTTPRequestOperationManager manager]setSecurityPolicy:security]; //
//普通一樣發(fā)起請(qǐng)求就可以
[[AFHTTPRequestOperationManager manager] POST:@"/test" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
- NSURLConnection 使用自簽證證書支持HTTPS,只需要在實(shí)現(xiàn)NSURLConnection的代理方法即可. 這個(gè)解決方法轉(zhuǎn)自GitHub JacksonTian 他原文中有多了行釋放代碼 CFRelease(trust); ,多了這行代碼在短時(shí)間重復(fù)請(qǐng)求,一個(gè)URL的時(shí)候trust 會(huì)提前釋放導(dǎo)致crash,沒有細(xì)究原因,直接注釋掉了.
#pragma Support NSURLCONNECTION HTTPS
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
static CFArrayRef certs;
if (!certs) {
//創(chuàng)建證書data
NSData*certData =[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HTTPS" ofType:@"cer"]];
SecCertificateRef rootcert = SecCertificateCreateWithData(kCFAllocatorDefault,CFBridgingRetain(certData));
const void *array[1] = { rootcert };
certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
// CFRelease(rootcert); // for completeness, really does not matter
}
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
int err;
SecTrustResultType trustResult = 0;
err = SecTrustSetAnchorCertificates(trust, certs);
if (err == noErr) {
err = SecTrustEvaluate(trust,&trustResult);
}
// BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed)||(trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified));
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];
}
// CFRelease(trust);
}
********后面通過測(cè)試****, ****不實(shí)現(xiàn)上面的委托****, NSURLConnection ****也可以直接連接****HTTPS****服務(wù)器****, ****這種是繞過了證書的****. afnetworking ****不設(shè)置安全策略就無(wú)法訪問****HTTPS****服務(wù)器****.****注****:afnnetworking****版本使用的是****2.5.4 ,****之前的版本關(guān)于安全策略的****API****有****bug ****在****afn****的****issue****中看到********