HTTPS从认识到线上实战全记录
https://www.cnblogs.com/liuxianan/p/https.html
前言
關(guān)于HTTPS,基本上你想知道的都在這里了(當(dāng)然僅限入門)。本文原標(biāo)題《HTTPS原理與實(shí)踐》,下圖是本文配套PPT的目錄截圖:
[TOC]
原理篇
2.1.?認(rèn)識HTTPS
先說一下,本文可能有些地方由于描述不到位或者我本人理解錯誤而出現(xiàn)不準(zhǔn)確內(nèi)容,有錯誤歡迎指正!
2.1.1.?什么是HTTPS
HTTPS全稱Hyper Text Transfer Protocol over Secure Socket Layer,直譯過來就是通過SSL實(shí)現(xiàn)的超文本傳輸協(xié)議,簡單來講就是加密版的HTTP協(xié)議,也就是HTTP+SSL/TLS。
為什么需要加密版的HTTP呢,因?yàn)槲覀兌贾?#xff0c;HTTP是明文傳輸?shù)?#xff0c;因此使用HTTP協(xié)議傳輸隱私信息非常不安全,很容易在傳輸過程中被竊取,或者通信內(nèi)容被人篡改冒充,使用HTTPS可以避免這些問題。
2.1.2.?SSL/TLS
為了解決HTTP明文傳輸?shù)娘L(fēng)險(xiǎn)性,網(wǎng)景公司設(shè)計(jì)了SSL(Secure Sockets Layer)協(xié)議用于對HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而就誕生了HTTPS。SSL目前的版本是3.0,被IETF(Internet Engineering Task Force)定義在RFC 6101中,之后IETF對SSL 3.0進(jìn)行了升級,于是出現(xiàn)了TLS(Transport Layer Security) 1.0,定義在RFC 2246。實(shí)際上我們現(xiàn)在的HTTPS都是用的TLS協(xié)議,但是由于SSL出現(xiàn)的時(shí)間比較早,并且依舊被現(xiàn)在瀏覽器所支持,因此SSL依然是HTTPS的代名詞。
上面一大段話是轉(zhuǎn)載的,簡單而言就是TLS是SSL的升級版,現(xiàn)在瀏覽器一般用的都是TLS。
2.1.3.?HTTPS的優(yōu)點(diǎn)
從底層分析HTTPS有以下3大優(yōu)點(diǎn):
從實(shí)際出發(fā)來看,HTTPS主要有以下優(yōu)點(diǎn):
下面單獨(dú)對3和4說一下。
運(yùn)營商HTTP劫持我們都知道,經(jīng)常莫名奇妙的在自己網(wǎng)站上看到各種惡意的惡心廣告,查看代碼發(fā)現(xiàn)被注入了一些奇奇怪怪的js,這其實(shí)就是HTTP劫持,啟用了HTTPS之后,我們傳輸?shù)膬?nèi)容都是加密的,運(yùn)營商想篡改內(nèi)容都沒轍。
為什么HTTPS能夠有效的解決DNS劫持呢?在域名被劫持的情況下,客戶端訪問的實(shí)際上是攻擊者的IP,客戶端通過這個IP找到攻擊者的服務(wù)器,要求建立HTTPS通信,因?yàn)楣粽邲]有真實(shí)服務(wù)器的證書和私鑰(想要申請這個域名的證書必須驗(yàn)證自己是這個域名的所有者,攻擊者做不到這一點(diǎn)),把偽造或自簽名的證書提供給客戶端,是得不到瀏覽器的認(rèn)可的,瀏覽器會彈出不安全的警告。但是用戶執(zhí)意要訪問我們也沒辦法,所以才用了有效解決而不是徹底解決這一詞。
另外,就近看的話,越來越多的場合強(qiáng)制要求https(比如ios、微信小程序等等都要求https),從長遠(yuǎn)看,升級HTTPS是大勢所趨,一次升級,永久受益。
2.1.4.?HTTPS的缺點(diǎn)
- 服務(wù)器性能下降,開啟HTTPS會增加內(nèi)存、CPU、網(wǎng)絡(luò)帶寬的開銷,特別是非對稱加密這一塊;
- 訪問速度下降,HTTP連接的建立需要3次握手,HTTPS還需要加上ssl的幾次握手(具體是幾次沒去考究,有說是9次),當(dāng)然下降主要是在第一次建立連接的時(shí)候,后面正常通信速度一般沒啥變化;
- 除了握手部分外,所有信息傳輸之后瀏覽器和服務(wù)器都要進(jìn)行加密解密,又是一筆額外的開銷;
- 申請證書需要一筆花費(fèi),當(dāng)然現(xiàn)在免費(fèi)證書也很容易申請到,這個不算明顯缺點(diǎn);
一句話概括就是:性能和速度下降,但是具體下降多少呢,這個不太好講,可以延伸閱讀:HTTPS 要比 HTTP 多用多少服務(wù)器資源?
2.1.5.?HTTPS原理
HTTPS主要分為單向認(rèn)證和雙向認(rèn)證,99%的場景都只需要單向認(rèn)證,雙向認(rèn)證我們后面再來講。
2.1.5.1.?小明和小紅的故事
在介紹HTTPS原理之前,我們先來假設(shè),假如讓我們自己設(shè)計(jì)一套加密方案該如何實(shí)現(xiàn)呢?為了更好理解,我們用人來舉個栗子:
小明(客戶端)暗戀小紅(服務(wù)端),想給小紅寫信,但是又怕信在郵遞的過程中被人偷看,所以他把信裝在一個盒子里鎖起來,信雖然是安全了,但是小紅就算收到了打不開啊,把鑰匙給小紅寄過去?萬一鑰匙也被人偷去了怎么辦?
就在這時(shí),小紅想到了一個辦法:小紅把一個沒有上鎖的盒子寄給小明(鑰匙在小紅這),小明把鑰匙放進(jìn)去再鎖上(小明可以鎖盒子,但是一旦鎖上了就連自己都打不開了),然后把這個裝有鑰匙的盒子寄回給小紅,因?yàn)樾〖t有鑰匙,所以能打開盒子拿到里面的鎖信件盒子的鑰匙,再然后就能看到小明給她寫的信了。同時(shí),小紅想回信的話,也可以把信裝在這個盒子里寄回去,因?yàn)檫@是小明的盒子,他自己肯定還有一把鎖,所以他也能打開,從此,小明和小紅就可以任意的寫信私通而不用擔(dān)心其他人能看到了!
但是,如何保證小紅寄送過來的未上鎖盒子不被別人調(diào)包呢?這個等到我們介紹完HTTPS原理之后我們再回過頭來看這個問題。
2.1.5.2.?單向認(rèn)證
下面這張圖是網(wǎng)上比較常見的一張圖:
這個應(yīng)該算是精簡版,省略了一些細(xì)節(jié),但是對于理解https的核心原理部分足夠了。下面這張圖可能更全面(圖片來源于這里,感謝作者)
具體過程如下:
至于為什么會有三個隨機(jī)數(shù)來生成最終的對稱加密密鑰,主要是為了進(jìn)一步增大密鑰的隨機(jī)性,這里有一段不錯的解釋:
不管是客戶端還是服務(wù)器,都需要隨機(jī)數(shù),這樣生成的密鑰才不會每次都一樣。由于SSL協(xié)議中證書是靜態(tài)的,因此十分有必要引入一種隨機(jī)因素來保證協(xié)商出來的密鑰的隨機(jī)性。
對于RSA密鑰交換算法來說,pre-master-key本身就是一個隨機(jī)數(shù),再加上hello消息中的隨機(jī),三個隨機(jī)數(shù)通過一個密鑰導(dǎo)出器最終導(dǎo)出一個對稱密鑰。
pre master的存在在于SSL協(xié)議不信任每個主機(jī)都能產(chǎn)生完全隨機(jī)的隨機(jī)數(shù),如果隨機(jī)數(shù)不隨機(jī),那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機(jī)因素,那么客戶端和服務(wù)器加上pre master secret三個隨機(jī)數(shù)一同生成的密鑰就不容易被猜出了,一個偽隨機(jī)可能完全不隨機(jī),可是是三個偽隨機(jī)就十分接近隨機(jī)了,每增加一個自由度,隨機(jī)性增加的可不是一。
需要特別注意的是,以上握手階段全部用的是HTTP協(xié)議明文傳輸?shù)摹?/p>
2.1.5.3.?回到小明和小紅的故事
介紹完HTTPS原理之后,我們再來回到小明和小紅的故事來加深理解。看起來讓小紅寄未上鎖盒子的方案很完美,但是,假如小紅寄過來的盒子被人調(diào)包了呢?調(diào)包的話打開情書的鑰匙就被別人拿走了。所以這時(shí)候需要有一家在江湖上比較有威望的鏢局(假設(shè)叫龍門鏢局)來幫忙押送小紅的盒子,當(dāng)小明收到盒子時(shí),如果是鏢局親自送過來的、并且說是小紅寄的盒子,那么小明就認(rèn)為這是小紅的盒子(小明很信任這家鏢局),前面我們說了,這家鏢局在江湖上很有威望,為了自己的聲譽(yù)它必須保證每一趟鏢都沒問題。有人又會問了,干嘛不直接讓鏢局把信送過去呢?因?yàn)樾∶鲗懶挪豢赡苤粚懸环?#xff0c;而且每封情書都讓鏢局來押送成本太大,而且鏢局比郵局流程更繁瑣,更費(fèi)時(shí)間,如果小明收到一個沒聽過的鏢局送過來的聲稱是小紅寄的盒子,那么他不會相信。
上面例子中,小明是瀏覽器,小紅是服務(wù)器,鏢局是頒發(fā)證書的CA(后面會提到),沒聽過的鏢局就是不受信任的根證書,鏢就是證書,信被別人看了叫HTTP明文泄露,信被別人改了叫HTTP劫持,信上的地址被人改了叫DNS劫持,小明寄給小紅的盒子是對稱加密(因?yàn)殡p方都有鑰匙,都能打開),小紅寄給小明的沒鎖的盒子可以看做是非對稱加密(因?yàn)樗腥硕伎梢阅盟用軚|西,但是一旦加密了就打不開,只有小紅一個人有鑰匙),鏢局自己干壞事自毀前程就等同于沃通的故事,等等。
2.1.5.4.?雙向認(rèn)證
雙向認(rèn)證和單向認(rèn)證原理基本差不多,主要區(qū)別是除了客戶端需要認(rèn)證服務(wù)端以外,服務(wù)端對客戶端也需要認(rèn)證。什么場景下需要驗(yàn)證客戶端呢?比如一些銀行業(yè)務(wù),銀行會要求客戶必須在電腦上插入它們簽發(fā)的U盾之類的東西,或者安裝什么控件,這里就類似客戶端證書的概念,沒有這個證書的人無法使用銀行提供的業(yè)務(wù)。
雙向認(rèn)證我沒有去親自嘗試,可以參考這篇文章。
下面還是上面那位網(wǎng)友畫的雙向認(rèn)證圖,我沒有仔細(xì)考究,先貼在這里:
2.1.6.?引申思考
2.1.6.1.?如何保證公鑰不被篡改
將公鑰放在數(shù)字證書中。只要證書是可信的,公鑰就是可信的。
那如何保證證書可信呢?證書的生成都是由國際頂級認(rèn)證機(jī)構(gòu)簽發(fā)的,簽發(fā)的時(shí)候必須驗(yàn)證你是不是這個域名的所有者,只有是才給你簽發(fā)證書(證書和域名一一掛鉤),所以理論上其他人無法偽造你的證書(只是理論上),即使偽造了,瀏覽器在加載的時(shí)候會進(jìn)行域名校驗(yàn),如果證書中的域名和實(shí)際域名不匹配,瀏覽器是會警告的。
問題又來了,瀏覽器怎么知道你的證書是不是合法的國際頂級認(rèn)證機(jī)構(gòu)簽發(fā)的呢?操作系統(tǒng)和瀏覽器都內(nèi)置了一些他們認(rèn)為可信任的國際頂級認(rèn)證機(jī)構(gòu)(CA,后面會提到),只有他們簽發(fā)的證書瀏覽器才信任。
2.1.6.2.?為何正式傳輸時(shí)使用對稱加密
因?yàn)榉菍ΨQ加密很慢,而且傳輸普通內(nèi)容時(shí)雙方都已經(jīng)拿到了隨機(jī)又沒有其他人知道的密碼,所以普通的對稱加密足矣。
2.2.?CA
2.2.1.?何為CA
CA(Certificate Authority),即證書認(rèn)證機(jī)構(gòu),它的作用就是提供證書(即服務(wù)器證書,由域名、公司信息、序列號和簽名信息組成)加強(qiáng)服務(wù)端和客戶端之間信息交互的安全性,以及證書運(yùn)維相關(guān)服務(wù)。任何個體/組織都可以扮演 CA 的角色,難的是你要能得到全世界各大操作系統(tǒng)、瀏覽器等的默認(rèn)信任,能得到他們的默認(rèn)信任,你也可以自己開一家CA公司了,這類證書通常叫做根證書。瀏覽器默認(rèn)信任的 CA 大廠商有很多,比如?Symantec賽門鐵克、Comodo、Godaddy、GolbalSign(百度微博等都是它簽發(fā)的) 和?Digicert。
如何查看操作系統(tǒng)內(nèi)置了哪些CA呢?Internet選項(xiàng)->內(nèi)容->證書->受信任的根證書頒發(fā)機(jī)構(gòu):
想讓你的https網(wǎng)站默認(rèn)情況下就被全世界瀏覽器信任你必須使用它們簽發(fā)的證書,大部分都是要錢的,當(dāng)然也有免費(fèi)的。
很多人一開始應(yīng)該有和我一樣的疑問,我升級我的https,憑啥要到別人那里花錢買證書(即使有免費(fèi)的也不爽)?,看到這里我想不用再多解釋你應(yīng)該懂了。
2.2.2.?CA如果作惡怎么辦
CA必須是絕對公平公正不作惡的,否則一旦暴露出來一些丑聞,立即會被各大瀏覽器和廠商拉入黑名單不再信任,或者各種降級處理,帶來的后果甚至可能是殺身之禍,比如被360收購的沃通的下場:谷歌宣布開始全面封殺使用沃通CA證書網(wǎng)站,信譽(yù)破產(chǎn)的惡果。
沃通的主要罪狀有五個:
沃通為何要偽造簽署日期呢?
由于如今的運(yùn)算能力越來越強(qiáng),SHA1 散列算法的可靠性越來越不夠了。一些主流的瀏覽器,如果發(fā)現(xiàn)2016元旦之后簽署的 CA 證書,依然采用 SHA1,會給出警告。沃通為了幫證書申請人規(guī)避瀏覽器警告,故意把簽署日期偽造成2015年底。
2.2.3.?頂級證書私鑰泄露怎么辦
如果頂級證書的私鑰泄露,那么帶來的后果是災(zāi)難性的,只能各大瀏覽器和操作系統(tǒng)通過更新補(bǔ)丁的方式來吊銷泄密的根證書,泄露之后一般這家CA公司離倒閉不遠(yuǎn)了,也不是沒有這樣的例子:
荷蘭CA供應(yīng)商DigiNotar因?yàn)楹诳腿肭质录蔀槿f眾矚目的焦點(diǎn),它發(fā)行的證書被眾多瀏覽器開發(fā)商和操作系統(tǒng)開發(fā)商宣布為不受信任。現(xiàn)在,這家失去信任的CA宣告破產(chǎn)。疑似伊朗黑客在7月中旬入侵了DigiNotar服務(wù)器,發(fā)行了531個偽造證書,包括了Google、微軟、雅虎、Twitter、Facebook、中情局、軍情六處和摩薩德等。DigiNotar在7月19日發(fā)現(xiàn)了入侵,但直到8月份外界才知道入侵事件。DigiNotar的母公司VASCO承認(rèn)損失慘重。
2.3.?SSL證書
2.3.1.?證書的種類
SSL 證書按大類一般可分為DV SSL?、OV SSL、EV SSL證書,又叫域名型、企業(yè)型、增強(qiáng)型證書:
- DV SSL(Domain Validation),域名型SSL證書,證書頒布機(jī)構(gòu)只對域名的所有者進(jìn)行在線檢查,只要你能證明你是這個域名的所有者就可以給你頒發(fā)證書,不會校驗(yàn)網(wǎng)站的資質(zhì),哪怕你是個黃賭毒網(wǎng)站也可以,個人網(wǎng)站、非盈利項(xiàng)目、開源項(xiàng)目等用域名型證書足矣;
- OV SSL(Organization Validation),企業(yè)型SSL證書,需要購買者提交組織機(jī)構(gòu)資料和單位授權(quán)信等在官方注冊的憑證,證書頒發(fā)機(jī)構(gòu)在簽發(fā) SSL 證書前不僅僅要檢驗(yàn)域名所有權(quán),還必須對這些資料的真實(shí)合法性進(jìn)行多方查驗(yàn),只有通過驗(yàn)證的才能頒發(fā) SSL 證書;
- EV SSL(Extended Validation),增強(qiáng)型SSL證書(EV SSL),驗(yàn)證流程更加具體詳細(xì),驗(yàn)證步驟更多,這樣一來證書所綁定的網(wǎng)站就更加的可靠、可信。它跟普通SSL證書的區(qū)別是瀏覽器的地址欄變綠,如果是不受信的 SSL 證書則拒絕顯示,如果是釣魚網(wǎng)站,地址欄則會變成紅色,以警示用戶。
不論是 DV、OV 還是 EV 證書,其加密效果都是一樣的,個人網(wǎng)站用DV證書、企業(yè)用OV足夠了。
如何查看證書類型?如下圖,百度是OV,github是EV(其實(shí)好像并沒有統(tǒng)一的區(qū)分方法,有的證書不會寫):
2.3.2.?證書的格式
一般來說,主流的 Web 服務(wù)軟件,通常都基于 OpenSSL 和 Java 兩種基礎(chǔ)密碼庫。
- Tomcat、Weblogic、JBoss等Web服務(wù)軟件,一般使用JDK自帶的Keytool工具,生成Java Keystore(JKS)格式的證書文件。
- Apache、Nginx等Web服務(wù)軟件,一般使用OpenSSL工具提供的密碼庫,生成?.key、.crt等格式的證書文件。
- IBM 的 Web 服務(wù)產(chǎn)品,如 Websphere、IBM Http Server(IHS)等,一般使用 IBM 產(chǎn)品自帶的 iKeyman 工具,生成 KDB 格式的證書文件。
- 微軟的IIS使用Windows自帶的證書庫生成pfx格式的證書文件。
詳見下圖:
每種格式之間都可以相互轉(zhuǎn)換,轉(zhuǎn)換方法可以參考阿里云給出的幫助文檔,在騰訊云申請證書的時(shí)候會自動幫你生成4種服務(wù)器各自需要的格式,非常方便。
2.3.3.?證書的收費(fèi)與免費(fèi)
不是說收費(fèi)的證書就一定比免費(fèi)證書好,只不過現(xiàn)階段各CA機(jī)構(gòu)為了自己的盈利目的,免費(fèi)證書一般都有一些限制,比如只支持單域名,子域名太多的話需要挨個申請。
實(shí)踐篇
本文全部以nginx配置為例,其它Web服務(wù)器配置請自行g(shù)oogle,或者參考這篇不錯的文章:SSL證書安裝指引。
3.1.?第一步,生成證書
首先我們需要得到一張證書,可以申請免費(fèi)的,也可以自制,本地測試時(shí)一般自制證書。
3.1.1.?申請免費(fèi)證書
免費(fèi)證書一般有下面幾種:
- Let's Encrypt:獲得Mozilla、微軟等主要瀏覽器廠商的根授信,出現(xiàn)的目的就是為了推廣HTTPS,缺點(diǎn)是只有3個月有效期,過期需續(xù)簽;
- TrustAsia亞洲誠信;
- StartSSL免費(fèi)DV證書:因丑聞被主流瀏覽器封殺,一般不建議;
- Wosign(沃通)免費(fèi)DV證書:同上,被各大瀏覽器封殺,基本可以無視了;
我們一般不需要自己直接和它們打交道,國內(nèi)的云服務(wù)提供商一般都有免費(fèi)的證書申請,這里操作會更簡單一點(diǎn)。
先聲明一下,這里不是打廣告,如果有更好用的,歡迎大家推薦。阿里云之前有一款免費(fèi)的SSL證書申請,但是現(xiàn)在好像下線了,騰訊云有一款TrustAsia的免費(fèi)證書,又拍云說是有2款免費(fèi)證書,而且可以自動續(xù)簽,但是試了一下發(fā)現(xiàn)必須把域名綁定到它們的CNAME才行,所以想想還是放棄了:
最后我用的是騰訊云免費(fèi)SSL證書,有一款TrustAsia的免費(fèi)證書,缺點(diǎn)是有效期只有1年(到期應(yīng)該可以重新申請),且不支持泛域名,如果子域名很多的話比如挨個申請,很麻煩,大家有更好用的歡迎推薦:
申請很簡單,簡單填寫資料,然后驗(yàn)證域名身份,快的話2-3分鐘內(nèi)就能成功申請到:
成功后可以把證書下載到本地,內(nèi)置了Apache、IIS、Nginx、Tomcat的4種證書格式,很方便。
申請到的證書:
3.1.2.?自制證書
雖然有很多途徑可以申請到免費(fèi)的證書,但一般都是單域名(不支持泛域名),限制太多,本地調(diào)試極不方便,所以我們希望本地開發(fā)時(shí)能夠使用我們自己簽發(fā)的證書。下面我們就來自己實(shí)踐一下如何從頭開始自制HTTPS證書。
證書一般都是用openssl來生成,當(dāng)然也可以用jdk自帶的keytool來生成,但是最終還是要用openssl來轉(zhuǎn)換格式,所以一般還是推薦用openssl來生成。
3.1.2.1.?安裝openssl
首先當(dāng)然還是安裝openssl,這里我們只介紹Windows平臺,Linux系統(tǒng)的請參考這里,點(diǎn)擊這里下載Win64位的安裝包:
安裝很簡單,安裝完畢之后為了使用方便,建議配置一下環(huán)境變量:
然后就可以隨時(shí)隨地執(zhí)行openssl命令了。
3.1.2.2.?生成CA根證書
我們先生成一個自己的CA根證書ca.crt,然后再用這個根證書生成服務(wù)端證書server.crt,有人會問,為啥不直接生成服務(wù)端證書呢?因?yàn)檫@樣做的話將來我們只要導(dǎo)入一個CA根證書,其它所有用它生成的證書都默認(rèn)是可信任的,方便嘛!
好了,說了這么多廢話,下面開始了:
# 生成CA私鑰 openssl genrsa -out ca.key 1024 # 生成CA根證書,-day指定證書有效期 openssl req -new -x509 -key ca.key -out ca.crt -days 365就這么簡單,第二步需要輸入幾個東西,雖然說亂填也可以,但建議按照提示來填,其中Common Name需要特別注意,如果是生成CA證書的話,可以輸入諸如My CA之類的,如果是生成服務(wù)端證書的話,必須輸入網(wǎng)站的域名,可以輸入泛域名,如*.haoji.me:
另外,如果報(bào)了unable to write 'random state'的錯誤,一般都是因?yàn)闆]有使用管理員權(quán)限打開命令行窗口。
3.1.2.3.?生成服務(wù)端證書
和CA證書的生成不同的時(shí),我們需要先生成一個csr證書請求文件文件(CSR,Cerificate Signing Request),有了這個文件之后再利用CA根證書生成最終的證書:
# 生成服務(wù)端私鑰 openssl genrsa -out server.key 1024 # 生成證書請求文件 openssl req -new -key server.key -out server.csr # 生成最終證書文件,-day指定證書有效期 openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt操作截圖:
但!是!各位看官先別急著去實(shí)踐,以上證書我在Chrome55下測試沒問題,但是Chrome61下測試提示Subject Alternative Name missing錯誤:
The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.提示必須指定DNS Name或者IP地址,而指定這個必須要用v3的證書。生成v3證書只需要比上面多加2個參數(shù)-extfile openssl.cnf -extensions v3_req,但是多了一個額外的配置文件,這個文件里面可以填很多東西(完整配置文件參考這里),我們這里僅僅需要指定subjectAltName即可。
先準(zhǔn)備一個名為openssl.cnf的文件,內(nèi)容如下:
[v3_req] subjectAltName = @alt_names[alt_names] DNS.1 = localhost.com DNS.2 = www.localhost.com DNS.3 = www.test123.com #IP.1 = 127.0.0.1解釋一下,這里的alt_names指的是最終可以訪問的域名或者IP,所以,其實(shí)一個證書是可以多個網(wǎng)站同時(shí)使用的。被訪問域名只要滿足DNS和IP中的一個,其證書就是合法的。
然后再來重新生成證書,為了對大家產(chǎn)生誤導(dǎo),我們再來一遍完整的過程:
# 生成服務(wù)端私鑰 openssl genrsa -out server.key 1024 # 生成證書請求文件 openssl req -new -key server.key -out server.csr # 生成最終證書文件,-day指定證書有效期 openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -extfile openssl.cnf -extensions v3_req -in server.csr -out server.crt雙擊生成的證書可以看到如下內(nèi)容:
3.1.2.4.?生成客戶端證書
如果需要實(shí)現(xiàn)HTTPS雙向認(rèn)證,還要按照上述服務(wù)端一模一樣的操作再生成一個client.crt和client.key,這里我們就不重述了,90%的場景都是不需要雙向認(rèn)證的。
3.1.2.5.?導(dǎo)入證書
上述步驟執(zhí)行完之后生成了如下文件:
我們只需要雙擊ca.crt導(dǎo)入這個自制根證書即可,以后只要是利用這個證書生成證書瀏覽器都會認(rèn)為是可信任的,這讓我想起了12306干的勾當(dāng),如果你能把你這個根證書推廣到全世界的電腦和手機(jī),那么你也可以成立一家CA公司專門賣證書了,哈哈。
導(dǎo)入的時(shí)候注意證書存儲位置:
由于這是很敏感的操作,所以操作系統(tǒng)一定會有警告:
3.1.3.?引申話題:12306為啥不申請證書
這個標(biāo)題在大約在半個月前還是正確的,但是,就在大約半個月前,12306終于買證書了!!!倔強(qiáng)的12306堅(jiān)持了這么多年推廣自己的證書,終于還是妥協(xié)了:
我們還是回到12306沒買證書以前。我們先回憶一下12306的做法,首頁不是https,它在首頁明顯位置放置了一個證書下載鏈接讓我們?nèi)ハ螺d,真正的購票頁面才開啟了https,沒安裝這個證書瀏覽器就會各種警告。
有很多人都在網(wǎng)上問,12306為啥沒買證書呢?是不舍得花這個錢嗎?當(dāng)然不是,堂堂鐵老大再怎么虧損多少個億,這點(diǎn)錢還是出得起的,12306無非就是想利用自己絕對壟斷地位推廣自己的SRCA證書而已(12306有一個中鐵數(shù)字證書認(rèn)證中心),至于推廣證書有什么用,這不用我多說吧。
摘抄一段網(wǎng)友的話:
合法證書對于SSL加密通信和通信完整性保護(hù)的意義就是合格鑰匙之于鎖的關(guān)系,你把山寨CA請到你家瀏覽器的受信任CA列表,就相當(dāng)于你從大馬路上撿把插著萬能鑰匙的鎖回家裝大門上。門上確實(shí)有鎖,沒鑰匙確實(shí)進(jìn)不來你家偷窺(機(jī)密性保護(hù))和盜竊(完整性保護(hù)),但有萬能鑰匙的人呢?
3.2.?第二步,nginx的ssl模塊安裝
3.2.1.?Windows系統(tǒng)
Windows平臺的nginx.exe一般內(nèi)置了ssl模塊,無需額外單獨(dú)安裝。
3.2.2.?Linux系統(tǒng)
linux系統(tǒng)的nginx一般都是編譯安裝的,如果你第一次安裝nginx的時(shí)候已經(jīng)安裝了ssl模塊的話,這一步可以跳過,如果沒有,繼續(xù)往下看。
如何查看有沒有安裝ssl模塊呢?定位到nginx/sbin目錄執(zhí)行nginx -V查看安裝時(shí)的命令,如果有--with-http_ssl_module,說明已經(jīng)安裝了ssl模塊,那么你可以跳過這一步了。
這里著重要講的是已經(jīng)上線運(yùn)行了一段時(shí)間的nginx如果安裝新模塊,其實(shí)下面的內(nèi)容在我另外一篇文章中有提到過。
3.2.2.1.?編譯安裝openssl
編譯安裝openssl要很久很久,做好心理準(zhǔn)備。
下載openssl-1.0.2n.tar.gz文件放在/home/nginx/下面:
cd /home/nginx tar -zxvf openssl-1.0.2n.tar.gz cd openssl-1.0.2n ./config make & make install3.2.2.2.?重新編譯nginx
nginx安裝新模塊需要整體重新編譯,所以需要知道上一次安裝時(shí)的編譯命令,假設(shè)nginx安裝在/home/nginx/nginx-1.8.1下面,定位到sbin下面執(zhí)行./nginx -V(注意V是大寫)后可以查看安裝時(shí)使用的命令:
[root@iZ94i7kwlagZ sbin]# ./nginx -V nginx version: nginx/1.8.1 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) built with OpenSSL 1.0.2n 7 Dec 2017 TLS SNI support enabled configure arguments: --prefix=/home/nginx/nginx-1.8.1 --with-pcre=/home/nginx/pcre-8.38 --with-zlib=/home/nginx/zlib-1.2.8 --without-http_ssi_module然后定位到源碼包去重新編譯,根據(jù)已有的命令再加上我們這次要安裝的新模塊命令,我這里是--with-openssl=/home/nginx/openssl-1.0.2n --with-http_ssl_module。注意,如果源碼包刪了,重新下載一個版本一致的nginx-1.8.1.tar.gz并解壓,為了區(qū)分,我解壓到/home/nginx/temp-nginx-1.8.1:
cd /home/nginx/temp-nginx-1.8.1 ./configure --prefix=/home/nginx/nginx-1.8.1 --with-pcre=/home/nginx/pcre-8.38 --with-zlib=/home/nginx/zlib-1.2.8 --with-openssl=/home/nginx/openssl-1.0.2n --with-http_ssl_module make切記這里僅僅需要make,不需要make install。執(zhí)行完之后我們在/home/nginx/temp-nginx-1.8.1/objs/下得到了一個新的二進(jìn)制文件nginx,上面所有操作都是為了得到這個文件,然后將這個文件覆蓋現(xiàn)有nginx文件即可(為了以防萬一,最好備份一下):
cd /home/nginx/nginx-1.8.1/sbin/ ./nginx -s stop # 先停止 cp ./nginx ./nginx.backup # 備份 cd /home/nginx/ cp temp-nginx-1.8.1/objs/nginx nginx-1.8.1/sbin/nginx # 覆蓋然后啟動nginx查看是否正常。
3.3.?第三步,nginx配置
3.3.1.?配置
假設(shè)我們有一個www.localhost.com的網(wǎng)站,為了方便測試,把它添加到hosts文件中去。
然后將第一步得到的證書復(fù)制到nginx/conf/crt/文件夾下(后面的crt是自己新建的文件夾),編輯nginx.conf:
http {# 省略其它配置server {listen 443; server_name www.localhost.com; ssl on; # 書寫路徑時(shí)注意,即使使用了include將conf文件寫到其它目錄,證書路徑依然是相對于nginx.conf而言的,且windows下不能以./開頭 ssl_certificate crt/server.crt; ssl_certificate_key crt/server.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 使用的協(xié)議 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 配置加密套件,寫法遵循openssl標(biāo)準(zhǔn) ssl_prefer_server_ciphers on; location / { root E:/github/test/dist/www; index index.html; } } }最主要就是中間那7行ssl開頭的配置,一般照著寫就可以了,替換一下自己的證書路徑,書寫路徑時(shí)注意,即使使用了include將conf文件寫到其它目錄,證書路徑依然是相對于nginx.conf而言的,并且Windows下不能以./開頭,否則會提示文件找不到。
運(yùn)行nginx -t測試一下是否OK:
D:\GreenSoft\nginx-1.11.8>nginx -t nginx: the configuration file D:\GreenSoft\nginx-1.11.8/conf/nginx.conf syntax is ok nginx: configuration file D:\GreenSoft\nginx-1.11.8/conf/nginx.conf test is successful沒問題就重啟nginx,然后打開瀏覽器測試,一切順利的話你可能已經(jīng)看到綠色的https前綴了,有木有很雞凍:
特別注意,由于我們還沒有做http自動跳轉(zhuǎn)處理,測試時(shí)一定要主動輸入https://www.localhost.com的完整域名!
3.3.2.?常見問題
3.3.2.1.?Mixed Content
https頁面出現(xiàn)http鏈接的資源我們稱之為Mixed Content(混合內(nèi)容),不同瀏覽器對不同類型的混合內(nèi)容處理方式不一樣,這里我們只講主流瀏覽器。現(xiàn)代瀏覽器(Chrome、Firefox、Safari、Microsoft Edge)基本上都遵守了W3C的Mixed Content規(guī)范,將其分為Optionally-blockable和Blockable兩類:
- Optionally-blockable主要是只危險(xiǎn)較小的圖片、視頻、音頻等資源,這類資源即使被人篡改也不會有太大的問題,瀏覽器默認(rèn)會加載,展示在控制臺會打印警告信息,并且https不是綠色的。
- Blockable一般是指除了上述之外所有的被限制加載的http資源,如JS、CSS、iframe等,瀏覽器會直接禁止加載,并且控制臺打印錯誤信息。
所以網(wǎng)站在升級https時(shí)需要特別注意,既然要升級就最好要全站升級,不然很容易出現(xiàn)某些資源由于寫死了http://頭導(dǎo)致瀏覽器無法加載的嚴(yán)重問題。當(dāng)然也不是沒有辦法解決,可以通過CSP的upgrade-insecure-requests指令讓網(wǎng)頁所有http資源自動指向https,限于篇幅,本文不對此展開講,讀者可自行了解CSP、HSTS等相關(guān)概念。
繼續(xù)回到正文,當(dāng)頁面有http資源時(shí),https不是綠色的:
將所有http鏈接改成https之后,綠色回來了:
3.3.2.2.?域名不匹配
我們還是用前面的例子,假如把nginx中的域名改成www.localhost2.com,同時(shí)hosts也改下,但是證書不變,然后再次打開瀏覽器訪問時(shí)提示NET::ERR_CERT_COMMON_NAME_INVALID:
所以,DV證書一定要是和域名掛鉤的,域名不匹配瀏覽器會攔截。
3.3.2.3.?根證書不受信任
假如我們前面自制的CA根證書沒有導(dǎo)入到操作系統(tǒng)(模擬時(shí)可以從Internet選項(xiàng)里面找到證書入口刪除之前的證書即可),然后瀏覽器會提示NET::ERR_CERT_AUTHORITY_INVALID:
3.3.2.4.?使用SHA-1簽名的證書
SHA-1在許多安全協(xié)議中廣泛使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec。早在2005年,密碼學(xué)家就證明SHA-1的破解速度比預(yù)期提高了2000倍,雖然破解仍然是極其困難和昂貴的,但隨著計(jì)算機(jī)變得越來越快和越來越廉價(jià),SHA-1算法的安全性也逐年降低,已被密碼學(xué)家嚴(yán)重質(zhì)疑。所以,各大瀏覽器相繼宣布將逐步停止對SHA-1簽名證書的支持。
所以在生成證書時(shí)一定要指定-sha256參數(shù)。
3.3.2.5.?證書刷新不及時(shí)
更換證書時(shí)最好重啟一下nginx然后多刷新2次防止未生效折騰半天;
3.4.?第四步,http自動跳轉(zhuǎn)
網(wǎng)站是升級https了,但是用戶又不知道,而且不輸入?yún)f(xié)議頭的話瀏覽器默認(rèn)都是按照http來加載,所以我們還要對http做301自動跳轉(zhuǎn)處理。
server {listen 80;server_name www.localhost.com;location / { rewrite ^(.*) https://www.localhost.com$document_uri permanent; } }上述自動跳轉(zhuǎn)配置會自動攜帶URL和參數(shù),例如,訪問?http://www.localhost.com/test.html?a=1?會自動跳轉(zhuǎn)到?https://www.localhost.com/test.html?a=1?。`
3.5.?第五步,網(wǎng)站代碼改造
這個根據(jù)實(shí)際網(wǎng)站的不同難易程度會有很大不同,例如,如果你是全站升級https,包括各類子域名,那么很簡單,全文搜索http,批量替換成//開頭即可。但是如果只是部分升級,比如主站升級了,子站沒升級,然后主站頁面又有各種子站的資源鏈接、跳轉(zhuǎn)等,這就麻煩了,這時(shí)候只能手動處理了。特別是針對子域名比較多的網(wǎng)站,免費(fèi)證書又都不支持泛域名,全部升級需要一個個去生成證書,然后配置,麻煩死了。
另外,為了安全起見,剛開始的時(shí)候建議靜態(tài)資源的站點(diǎn)(比如圖片,很有可能外站引用了這個圖片鏈接)同時(shí)保持http和https都可以訪問,等時(shí)間成熟了再下掉或者做301重定向,否則很容易出現(xiàn)某個資源加載不了導(dǎo)致404的問題。
升級https最麻煩的可能就是這一步了,特別是對于歷史悠久的大網(wǎng)站,當(dāng)然小網(wǎng)站就另當(dāng)別論了。
其它
4.1.?CSP
CSP,全稱Content Security Policy,意即內(nèi)容安全策略,有非常多的指令,用來實(shí)現(xiàn)各種各樣與頁面內(nèi)容安全相關(guān)的功能,這里介紹2個比較有用的。所有CSP指令都有2種啟用方式,一種是HTTP頭部,一種是<meta>標(biāo)簽。
4.1.1.?禁用http鏈接
前面說過,對于HTTPS頁面中的圖片等資源瀏覽器默認(rèn)會加載,僅僅是控制臺給一個警告,因?yàn)閳D片類資源被劫持通常問題不會太大,但有些頁面按鈕布局等是用圖片做的,圖片被篡改會影響用戶使用,最重要的,頁面只要有一個http的鏈接,地址欄的https就不是綠色的。
可以通過CSP的block-all-mixed-content指令讓頁面進(jìn)入對Mixed Content的嚴(yán)格檢測(Strict Mixed Content Checking)模式。在這種模式下,所有非 HTTPS 資源都被禁止加載,控制臺報(bào)錯,https回歸綠色。
HTTP響應(yīng)頭方式:
Content-Security-Policy: block-all-mixed-contentHTML標(biāo)簽方式:
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">4.1.2.?強(qiáng)制http指向https
HTTP遷移HTTPS對于一些大型網(wǎng)站來說工作量巨大,難免有疏漏的地方,此時(shí)可以讓瀏覽器幫我們做http自動跳轉(zhuǎn)https這一步。通過upgrade-insecure-requests這個CSP指令,可以讓瀏覽器幫忙做這個轉(zhuǎn)換,啟用這個策略后,不僅是http靜態(tài)資源,http接口調(diào)用也會自動轉(zhuǎn)成https再發(fā)出去。
這里只介紹HTML標(biāo)簽方式:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">效果如下圖,http的圖片自動變成https:
4.2.?HSTS:防止HTTPS降級劫持
99%的人訪問一個網(wǎng)站都不會主動輸入http前綴,https就更是如此,因?yàn)橛脩粲植恢滥愕木W(wǎng)站是不是https的,所以幾乎所有的https網(wǎng)站都是通過http的301/302自動跳轉(zhuǎn)的方式來讓用戶進(jìn)入。注意,由于第一次是http訪問,如果第一次訪問就被劫持那用戶根本到不了https頁面,這就叫https降級劫持。
這個問題可以通過HSTS(HTTP Strict Transport Security)來解決。HSTS是一個響應(yīng)頭,格式如下:
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]- max-age,單位是秒,用來告訴瀏覽器在指定時(shí)間內(nèi)這個網(wǎng)站必須通過 HTTPS 協(xié)議來訪問,比如說我設(shè)置一年,那么一年以內(nèi)即使用戶輸入http并且被劫持了,瀏覽器依然會以HTTPS的方式來訪問;
- includeSubDomains,可選參數(shù),如果指定這個參數(shù),表明這個網(wǎng)站所有子域名也必須通過 HTTPS 協(xié)議來訪問。
- preload,可選參數(shù),是否啟用preload list,關(guān)于這個是什么后面再介紹。
注意HSTS這個響應(yīng)頭是添加到HTTPS響應(yīng)頭中而不是HTTP響應(yīng)的,這可能和我們預(yù)期的不一樣,如果一個HTTPS網(wǎng)站從來沒被訪問過,那這個HSTS頭永遠(yuǎn)生效不了,那怎么辦呢?瀏覽器廠商們?yōu)榱私鉀Q這個問題,提出了一個HSTS Preload List方案:內(nèi)置一份可以定期更新的啟用HSTS的域名列表,對于列表中的域名,即使用戶之前沒有訪問過,也會使用 HTTPS 協(xié)議。看起來這個主意挺餿的,但這也是沒辦法的辦法。想要加入這個列表需要很多強(qiáng)制要求,而且滿足了也不一定能申請成功,我們這里就不細(xì)講了。
另外,啟用HSTS必須使用默認(rèn)的 443 端口;必須使用域名,不能是 IP。而且啟用 HSTS 之后,一旦網(wǎng)站證書錯誤,用戶無法選擇忽略。
建議:只要你不能確保永遠(yuǎn)提供 HTTPS 服務(wù),就不要啟用。因?yàn)橐坏?HSTS 生效,你再想把網(wǎng)站重定向?yàn)?HTTP,之前的老用戶會被無限重定向,唯一的辦法是換新域名。
4.3.?Fiddler抓包HTTPS
默認(rèn)情況下Fiddler不會對HTTPS網(wǎng)站抓包,要啟用的話步驟如下:
Tool?->?Fiddler Options:
然后在IE代理中啟用對HTTPS的代理(默認(rèn)僅開啟了HTTP):
Fiddler會為每一個網(wǎng)站動態(tài)頒發(fā)一個*.xxx.com的證書,想要看網(wǎng)站真正證書時(shí)需關(guān)閉Fiddler:
所以,如果開發(fā)時(shí)使用Fiddler做代理的話,我們上面那么一大段自己生成證書的步驟可以省略了,哈哈,當(dāng)然自己掌握了這個過程也不多余。
4.4.?手機(jī)抓包HTTPS
需求:手機(jī)訪問電腦本機(jī)的某個HTTPS網(wǎng)站,而且是用了Fiddler的Willow插件修改了域名的網(wǎng)站。
手機(jī)上長按已經(jīng)連接的WIFI->修改網(wǎng)絡(luò)->高級->手動設(shè)置代理,代理地址就是你電腦的局域網(wǎng)IP,端口就是上面的8888,保存。
此時(shí)直接訪問是不行的,因?yàn)镕iddler默認(rèn)禁用了遠(yuǎn)程訪問,開啟方法如下,注意勾選之后必須重啟Fiddler,否則不會生效(開始還以為是防火墻問題):
此時(shí)使用手機(jī)訪問HTTP網(wǎng)站沒問題,但是訪問HTTPS時(shí)會提示證書不受信任,這是因?yàn)檫€沒有安裝Fiddler的根證書(Fiddler對HTTPS進(jìn)行代理時(shí)會使用自己的根證書對每一個訪問的網(wǎng)站動態(tài)生成證書,具體細(xì)節(jié)可以自行百度),手機(jī)訪問http://你的IP:8888,點(diǎn)擊頁面的FiddlerRoot certificate鏈接下載安裝證書,安裝成功后即可順利訪問部署在電腦本機(jī)的HTTPS網(wǎng)站了。
參考
- SSL證書安裝指引
- 關(guān)于啟用 HTTPS 的一些經(jīng)驗(yàn)分享(一)
- CHINASSL自2016年1月1日起全面停止簽發(fā)SHA-1證書
- Mozilla 將不再信任 WoSign 和 StartCom 頒發(fā)的新證書
- 沃通SSL證書事件全程回顧
- 谷歌宣布開始全面封殺使用沃通CA證書網(wǎng)站,信譽(yù)破產(chǎn)的惡果
- Let's Encrypt 上線的意義?
- SSL/TLS協(xié)議運(yùn)行機(jī)制的概述
- Https單向認(rèn)證和雙向認(rèn)證
- httpd設(shè)置HTTPS雙向認(rèn)證
- 主流數(shù)字證書都有哪些格式?
- SSL 證書服務(wù),大家用哪家的?
- 細(xì)說 CA 和證書
- Content Security Policy Level 2 介紹
- OpenSSL生成v3證書方法及配置文件
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/8192871.html
總結(jié)
以上是生活随笔為你收集整理的HTTPS从认识到线上实战全记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中小型研发团队架构实践:电商如何做企业总
- 下一篇: 转变--一个平凡人的2017年总结及20