背景
谷歌從 2017 年起纹磺,Chrome 瀏覽器將也會(huì)把采用 HTTP 協(xié)議的網(wǎng)站標(biāo)記為「不安全」網(wǎng)站傍睹;蘋(píng)果從 2017 年 iOS App 將強(qiáng)制使用 HTTPS憔杨;在國(guó)內(nèi)熱火朝天的小程序也要求必須使用 HTTPS 請(qǐng)求趁啸。
1: 什么是HTTPS?
在說(shuō)HTTPS之前先說(shuō)說(shuō)什么是HTTP巨缘,HTTP就是我們平時(shí)瀏覽網(wǎng)頁(yè)時(shí)候使用的一種協(xié)議。HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的散庶,也就是明文的蕉堰,因此使用HTTP協(xié)議傳輸隱私信息非常不安全。為了保證這些隱私數(shù)據(jù)能加密傳輸督赤,SSL(Secure Sockets Layer)協(xié)議用于對(duì)HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而就誕生了HTTPS泻蚊。SSL 3.0進(jìn)行了升級(jí)躲舌,于是出現(xiàn)了TLS(Transport Layer Security)。目前蘋(píng)果要求原文:The protocol Transport Security Layer (TLS) must be at least version 1.2性雄。
2: HTTPS原理
可以參考這份資料:https握手流程没卸。 里面介紹了單向雙向加密流程以及區(qū)別自行查看羹奉。
3: 什么樣的證書(shū)滿足條件呢?
第一種是創(chuàng)建證書(shū)請(qǐng)求约计,然后到權(quán)威機(jī)構(gòu)認(rèn)證诀拭,隨之配置到服務(wù)器;
第二種是自建證書(shū)煤蚌,需要自己配置給服務(wù)器耕挨。
看文檔描述:
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这橙。
傳輸安全協(xié)議層(TLS)必須至少1.2版:看下圖谷歌的證書(shū)信息奏窑。
接的加密方式需要提供“Foward Secrecy”,下面是支持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ū)的合法性,注意是否有效,iOS要求連接的HTTPS站點(diǎn)必須為CA簽名過(guò)的合法證書(shū)屈扎。
看幾個(gè)不符合條件證書(shū)的例子:
AFN 可以通過(guò)allowInvalidCertificates 來(lái)針對(duì)以上情況設(shè)置
allowInvalidCertificates 是否允許無(wú)效證書(shū)(也就是自建的證書(shū))埃唯,默認(rèn)為NO//如果是需要驗(yàn)證自建證書(shū),需要設(shè)置為YES
我們可以自己用命令驗(yàn)證下證書(shū)合法性助隧。
下面這個(gè)都是Fail
看一個(gè)沒(méi)問(wèn)題的證書(shū):
4:自建證書(shū)的流程
//第一步,為服務(wù)器端和客戶端準(zhǔn)備公鑰并村、私鑰
# 生成服務(wù)器端私鑰
openssl genrsa -outserver.key1024
# 生成服務(wù)器端公鑰
openssl rsa -inserver.key -pubout -outserver.pem
//第二步巍实,生成 CA 證書(shū)
# 生成 CA 私鑰
openssl genrsa -outca.key1024
# X.509 Certificate Signing Request (CSR) Management.
openssl req -new-key ca.key -outca.csr
# X.509 Certificate Data Management.
openssl x509 -req -inca.csr -signkey ca.key -outca.crt
//第三步,生成服務(wù)器端證書(shū)# 服務(wù)器端需要向 CA 機(jī)構(gòu)申請(qǐng)簽名證書(shū)哩牍,在申請(qǐng)簽名證書(shū)之前依然是創(chuàng)建自己的 CSR 文件
openssl req -new -key server.key-outserver.csr
# 向自己的 CA 機(jī)構(gòu)申請(qǐng)證書(shū)棚潦,簽名過(guò)程需要 CA 的證書(shū)和私鑰參與,最終頒發(fā)一個(gè)帶有 CA 簽名的證書(shū)
openssl x509 -req -CA ca.crt-CAkeyca.key-CAcreateserial-inserver.csr-outserver.cr
第四步膝昆,生成cer文件
使用openssl 進(jìn)行轉(zhuǎn)換
openssl x509 -inserver.crt-outserver.cer-outform der
如果對(duì)以上命令不是太熟悉可以查下丸边。或者看下圖荚孵。
可以用命令看看自己生成的一些東西一般在/Users/自己名字下面 ?ls 看列出來(lái)的如下圖:
5:把證書(shū)配置到服務(wù)器
我用的XAMPP 本機(jī)搭建的服務(wù)器如下圖:
注意:低版本的Mac OS 系統(tǒng)妹窖,Mysql 可能不能自動(dòng)啟動(dòng),需要用命令自己?jiǎn)?dòng) : sudo /Applications/XAMPP/xamppfiles/bin/mysql.serverstart
配置修改httpd-ssl.conf文件 把server.crt和server.key的路徑修改對(duì)就好了 由于我的服務(wù)器默認(rèn)開(kāi)啟ssl收叶,因此我就修改下證書(shū)路徑就好了骄呼。
來(lái)在瀏覽器看下結(jié)果
Google比較嚴(yán)格看下圖:
以上是自建證書(shū)的流程可以自己玩玩。
6:創(chuàng)建證書(shū)請(qǐng)求,然后到權(quán)威機(jī)構(gòu)認(rèn)證蜓萄,隨之配置到服務(wù)器
由于我們服務(wù)器已經(jīng)有了隅茎,我給后臺(tái)要一直沒(méi)反應(yīng),沒(méi)給我嫉沽,我就自己獲取了通過(guò)命令 辟犀。我們可以使用以下openssl命令來(lái)獲取到服務(wù)器的公開(kāi)二進(jìn)制證書(shū)。
openssl s_client -connect www.example.com.cn:443 /dev/null | openssl x509 -outform DER > https.cer
7:iOS客戶端的適配
單向認(rèn)證 SSL 協(xié)議不需要客戶擁有 CA 證書(shū)绸硕,只需將服務(wù)器端驗(yàn)證客戶證書(shū)的過(guò)程去掉堂竟。雙向認(rèn)證這種情況要求服務(wù)器和用戶雙方都有證書(shū)。
[self.sessionManagersetSecurityPolicy:[NKNetWorkCentercustomSecurityPolicy]];
+ (AFSecurityPolicy*)customSecurityPolicy
{
// /先導(dǎo)入證書(shū)
NSString*cerPath = [[NSBundlemainBundle]pathForResource:@"https"ofType:@"cer"];//證書(shū)的路徑
NSData*certData = [NSDatadataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate使用證書(shū)驗(yàn)證模式
AFSecurityPolicy*securityPolicy = [AFSecurityPolicypolicyWithPinningMode: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=@[certData];
returnsecurityPolicy;
}
下面是用花瓶抓包的結(jié)果
8:對(duì)于一些第三方http請(qǐng)求的處理
要么他們升級(jí)进倍。要么加入ATS 白名單里。