首先上自簽證書(shū)AFN需要修改的代碼:
+ (AFSecurityPolicy*)customSecurityPolicy
{
// /先導(dǎo)入證書(shū)
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"xxxx" ofType:@"cer"];//證書(shū)的路徑
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用證書(shū)驗(yàn)證模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates 是否允許無(wú)效證書(shū)(也就是自建的證書(shū))冶共,默認(rèn)為NO
// 如果是需要驗(yàn)證自建證書(shū)乾蛤,需要設(shè)置為YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES捅僵;
//假如證書(shū)的域名與你請(qǐng)求的域名不一致家卖,需把該項(xiàng)設(shè)置為NO;如設(shè)成NO的話庙楚,即服務(wù)器使用其他可信任機(jī)構(gòu)頒發(fā)的證書(shū)上荡,也可以建立連接,這個(gè)非常危險(xiǎn)馒闷,建議打開(kāi)酪捡。
//置為NO,主要用于這種情況:客戶端請(qǐng)求的是子域名纳账,而證書(shū)上的是另外一個(gè)域名逛薇。因?yàn)镾SL證書(shū)上的域名是獨(dú)立的,假如證書(shū)上注冊(cè)的域名是www.google.com疏虫,那么mail.google.com是無(wú)法驗(yàn)證通過(guò)的永罚;當(dāng)然,有錢(qián)可以注冊(cè)通配符的域名*.google.com卧秘,但這個(gè)還是比較貴的呢袱。
//如置為NO,建議自己添加對(duì)應(yīng)域名的校驗(yàn)邏輯翅敌。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = [[NSArray alloc]initWithObjects:certData, nil];
return securityPolicy;
}
+ (void)initialize
{
if (!requestManager) {
requestManager = [AFHTTPRequestOperationManager manager];
[requestManager setSecurityPolicy:[self customSecurityPolicy]];
}
}
cer文件是服務(wù)器同事給你的羞福,你添加到工程就可以了。
如果服務(wù)器給的是crt文件蚯涮,就需要自己轉(zhuǎn)換下:
需要cd到證書(shū)所在路徑
openssl x509 -in 你的證書(shū).crt -out 你的證書(shū).cer -outform der
關(guān)于證書(shū)的相關(guān)要求需要注意以下幾點(diǎn):
These are the App Transport Security requirements:
The protocol Transport Security Layer (TLS) must be at least version 1.2.
Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
Certificates must use at least an SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256 bit or greater Elliptic-Curve (ECC) key.
根據(jù)原文描述治专,首先必須要基于TLS 1.2版本協(xié)議。再來(lái)就是連接的加密方式要提供Forward Secrecy遭顶,文檔中羅列出支持的加密算法看靠。最后就是證書(shū)至少要使用一個(gè)SHA256的指紋與任一個(gè)2048位或者更高位的RSA密鑰,或者是256位或者更高位的ECC密鑰液肌。如果不符合其中一項(xiàng),請(qǐng)求將被中斷并返回nil鸥滨。
支持forward secrecy的加密方式:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
下面是我自己用的自簽證書(shū)的部分信息
有很大情況會(huì)出現(xiàn)NSURLErrorDomain -1012這個(gè)問(wèn)題:
你可以使用以下命令去獲取服務(wù)器的公開(kāi)二進(jìn)制證書(shū):
openssl s_client -connect www.baidu.com:443 </dev/null 2>/dev/null | openssl x509 -outform DER > https.cer
你把百度的域名換成自己服務(wù)器的去生成嗦哆。
如果是經(jīng)過(guò)第三方認(rèn)證的就換掉域名就可以了谤祖,其他都不需要?jiǎng)印?/p>
如果需要知道是否符合ATS要求,使用命令:
nscurl --ats-diagnostics --verbose https://example.com
我們可以看看百度返回的:
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"www.baidu.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
然后我們看看怎么添加http例外
在info.plist里面添加這些屬性老速。用紅線擦掉的就是域名粥喜;然后設(shè)置下面兩個(gè)屬性
關(guān)于域名比如:http://appweb.xxxx.com
我們填寫(xiě)的是xxxx.com就是一級(jí)域名或者叫二級(jí)域名com頂級(jí)域名前面那個(gè)就可以了。
最后關(guān)于CA.cer(自簽的根證書(shū))證書(shū)導(dǎo)入項(xiàng)目不能正常和服務(wù)器驗(yàn)證問(wèn)題橘券。下面是我的根證書(shū)一些信息:
因?yàn)槲覀児井a(chǎn)品需要幾個(gè)域名或者IP额湘,當(dāng)某個(gè)出現(xiàn)問(wèn)題能自動(dòng)切換到另外一個(gè)。這就導(dǎo)致可能需要幾個(gè)cer證書(shū)旁舰。如果能用根證書(shū)就不需要一個(gè)域名對(duì)應(yīng)一個(gè)證書(shū)锋华,但是一直不能跑起來(lái)。
為了驗(yàn)證箭窜,我們把CA證書(shū)通過(guò)郵件發(fā)送到iPhone手機(jī)毯焕。然后在描述文件里面手動(dòng)安裝(好像必須要用蘋(píng)果自帶的郵箱)。然后跑起來(lái)了磺樱。
我個(gè)人認(rèn)為是因?yàn)樽院灥腃A證書(shū)是不受蘋(píng)果信任的第三方機(jī)構(gòu)頒發(fā)的纳猫。所以不管你怎么設(shè)置都是不能像上面一樣成功。除非在手機(jī)自己安裝