HTTPS網站相信對很多工程師來講并不陌生,各大Web服務器產品都提供了詳細的配置方案,搭建起來也并不很難。但要說出其中的安全原理,卻不是件容易的事。今天我們就來談一談它后面的密碼學原理,希望通過這篇文章,大家能夠真正了解掌握相關的安全技術。強烈建議您讀這篇文章下面的內容之前,先看一下之前關于非對稱加密、數字簽名、數字證書的文章,做為相關知識儲備。
我們談HTTPS的安全,實際上是談SSL的安全,因為HTTPS實質就是HTTP+SSL。而其實SSL也不是完全準確的說法,因為作為協議的SSL(SecureSockets Layer 安全套接層)已經及其繼任者TLS協議(Transport Layer Security傳輸層安全)取代了。習慣使然,我們仍把這一套相關技術叫做SSL。SSL將非對稱加解密、數字簽名、數字證書等核心PKI技術應用在網絡通信的傳輸層,實現了服務器/客戶端認證和數據加密,保證了網絡中傳輸數據的安全。
先介紹一下應用最廣的服務器認證。服務器認證也叫單向認證,即客戶端瀏覽器訪問HTTPS網站時,先要對網站的真實性進行認證,認證通過后,客戶端與網站之間的數據交換以密文形式進行。具體的認證過程,不是本文的重點,因為你在其他很多介紹SSL的文章上都可以看到詳細的描述。本文重點是它的密碼學原理,先看下圖。
這張圖畫出了單向認證的核心過程。認證時,網站服務器先將自己的服務器證書發(fā)送給客戶端,客戶端收到證書后進行以下四項檢查:
l 證書是否過期就是檢查當前時間是否在證書有效期內;
l 證書是否由可信任CA頒發(fā)在數字證書那一篇里介紹過;
l 證書是否被吊銷就是指當前證書是不是已經被頒發(fā)它的CA吊銷了??蛻舳藱z查證書是否吊銷有CRL和OCSP兩種方法。CRL即證書吊銷列表,里面有CA已經吊銷了的證書集合,客戶端通過檢查CRL就可以判斷證書是否被吊銷。CRL是可以根據一定的算法更新的。OCSP是在線證書狀態(tài)檢查協議,客戶端直接向證書簽發(fā)機構發(fā)起查詢請求以確認該證書是否有效;
l 證書主題(持有人)名稱中的域名與你要訪問網站的域名是否一致。
如果上面四項有任何一項檢查結果為否,瀏覽器就會給出相關警告提示,如下圖是頒發(fā)證書的CA不被信任時的提示。
而這是網站域名與證書持有人的名稱不一致的情況。注意,這里并不要求持有人的名稱和網站名稱一致,而是指持有人的域名和完整域名一致。
一旦出現了這些警告,瀏覽器都會強烈建議用戶不要繼續(xù)訪問(當然Chrome比IE更強烈,下圖是IE打開同一個網站的提示,請細品個中的不同),
但最終要不要繼續(xù)訪問,決定權還在用戶手里。因此,客戶端驗證服務器證書這一步,實際上是由客戶端瀏覽器檢查和用戶自行判斷共同完成的。很多人在學習SSL時總問驗證服務器證書這一步是怎么驗證的,其實就是由用戶自己人工完成的,我們也可以叫它“人肉驗證”。你如果無視這些警告,繼續(xù)訪問,就表明你已經認同了這張服務器證書,也就等于認同了這個網站。相信很多人和我以前一樣,遇到這樣的警告都是馬上找繼續(xù)訪問的按鈕,基本不看到底警告了什么。如果自己開發(fā)的業(yè)務系統這樣做問題不大,但要是在互聯網上訪問第三方的網站,遇到這樣的警告還是要小心謹慎,一定要確保真的沒問題才可以訪問。很多中間人攻擊就是利用了用戶這種麻痹大意的心理得手的。
完成了服務器證書驗證最重要的一步后,下面的工作就是水到渠成了??蛻舳藭梢粋€隨機數作為生成對稱密鑰的數據,叫預主密鑰,然后用服務器證書的公鑰加密這個密鑰,并把這個加密的密鑰傳送給服務器,服務器用自己的私鑰解密??蛻舳伺c服務器根據相同的預主密鑰計算出對稱密鑰(其實這一步還有其他隨機數參與,這里就不再展開了),雙方使用對稱密鑰加密發(fā)送的數據,解密接收的數據,最終建立了網絡傳輸的安全通道。
在服務器認證的基礎上,SSL支持對客戶端的認證,這樣單向認證就變成了雙向認證。實現雙向認證要先做一個準備工作:用戶需要先將其證書登記在服務器的證書信任庫或數據庫中,并與被授權訪問服務器的用戶賬戶綁定。
與單向認證相比,紅色步驟就是雙向認證增加的部分。客戶端會進行對數據的簽名,在TLS協議中這個生成簽名的數據是之前的握手信息,然后把簽名結果(包括用戶證書)和加密的隨機數一起發(fā)送給服務器。服務器收到后,要驗證簽名后及用戶的證書。這個驗證過程除了有效期、是否被吊銷以及頒發(fā)CA是否被可信外,還需要在服務器的證書信任庫或數據庫里進行對比,以確定當前用戶的身份。驗證通過后,再按照單向認證的步驟解密隨機數,生成對稱密鑰。在實際使用時,瀏覽器會彈出窗體讓用戶選擇要發(fā)送的證書,如下圖。如果證書是用USBKey載體,則會彈出輸入口令對話框,完成數字簽名。這就是雙因素認證。
上述雙向認證過程可能和有些網上文章描述的不同,那些文章描述的是在雙向認證中,客戶端直接把自己的證書發(fā)送給服務器,而不是簽名,之后服務器先用客戶端公鑰加密服務器選定的對稱加密方案,客戶端收到后使用私鑰解密得到。上述描述應該是之前SSL協議的內容,并不是現在TLS協議的雙向認證過程。
SSL的優(yōu)點在于配置相對簡單,應用層改動很小。如果是單向認證,你的網站甚至不用改一行代碼,配置服務器即可,因為它作用在傳輸層,對應用層來講是透明的。但也正是因為這樣,是用SSL的HTTPS也有以下缺點:
多次握手協議和傳輸數據的加解密會帶來網頁訪問速度變慢,網絡資源消耗增大;
使用界面(如客戶端認證時的證書選擇的對話框)無法與應用層的界面保持一致,影響用戶瀏覽體驗;
在網頁中不能引用其他非安全資源,說白了就是不能嵌入http協議的鏈接。這并不是跨域的問題,而是瀏覽器認為不安全。不過,如果訪問的是本地資源,比如,大部分瀏覽器是認為沒問題的;
SSL證書需要花錢。雖然你自己也可以簽發(fā)一個SSL證書做服務器認證,技術上和那些大廠SSL證書沒有任何區(qū)別。但自己簽發(fā)證書的CA是不被信任的,你也不可能一個個通知用戶去手動把簽發(fā)CA的根證書裝到信任頒發(fā)機構里。所以,使用Windows已經預裝的那些受信任根CA或它們的分支機構簽發(fā)的SSL證書是普遍的選擇。SSL證書按年收費,費用在每年幾百元到幾千元不等。具體使用哪一種證書,要看網站的定位;
早期的SSL1.0、SSL2.0都有漏洞,相信做過平臺漏掃的同學對此都不陌生;
另外有些觀點認為SSL不能隱藏用戶隱私信息,不能認證用戶真實身份。我個人認為這并不是SSL做的事,這是應用層的問題。總之,使用基于SSL的HTTPS,能夠有效地降低傳輸數據被竊取的風險,增加網站被中間人劫持攻擊的難度。各位老鐵,能用還是都用了吧。