用Nginx搭建HTTPS服務(wù)器

摘要

本文主要是在測試https服務(wù)時(shí)對(duì)搭建https服務(wù)器的一些實(shí)踐總結(jié)瞭亮。TLS協(xié)議的介紹部分來源于對(duì)RFC5246的理解优幸,不當(dāng)之處,還請指出。后面包含一段對(duì)https的性能分析的工程實(shí)踐珠月。


1 TLS協(xié)議簡介
1.1 簡介

TSL是傳輸層安全協(xié)議(Transport Secure Protocol)的簡稱,它的前身是SSL(Secure Sockets Layer)楔敌。TLS的設(shè)計(jì)目標(biāo)是為互聯(lián)網(wǎng)通信提供安全保證啤挎,防止數(shù)據(jù)被竊聽,篡改卵凑。TLS協(xié)議由記錄層(TLS Record Layer)和握手層(TLS Handshake Layer)組成庆聘,記錄層處于協(xié)議的最低層,為TLS協(xié)議提供安全可靠的連接勺卢。TLS在協(xié)議棧中處于HTTP和TCP協(xié)議之間伙判,但是TLS協(xié)議是獨(dú)立于應(yīng)用層協(xié)議的,也就是說高層的應(yīng)用層協(xié)議黑忱,如HTTP宴抚,F(xiàn)TP等都可以創(chuàng)建在TLS之上勒魔,TLS的下層可以是任何可靠傳輸層協(xié)議,如TCP菇曲,SPX等冠绢。

1.2 TLS的版本演進(jìn)
發(fā)布時(shí)間 版本 RFC地址
N/A SSL1.0
1995 SSL2.0 rfc6176
1996 SSL3.0
1999 TLS1.0
2006 TLS1.1
2008 TLS1.2 rfc5246

TLS目前已發(fā)布的最新版本是TLS1.2,它在RFC5246中定義常潮,其前身SSL1.0弟胀,SSL2.0和SSL3.0。SSL由于安全漏洞喊式,已逐漸在被淘汰孵户;TLS1.0和SSL3.0差異很小,幾乎等同岔留,漸漸也不再使用延届,所以現(xiàn)在的話,只要注意TLS1.1以上的版本贸诚。

1.3 TLS握手過程

TLS分為記錄層協(xié)議和握手層協(xié)議:
記錄層協(xié)議(TLS Record Protocol)
記錄層協(xié)議負(fù)責(zé)將要發(fā)出的消息進(jìn)行分片方庭,壓縮,打上消息認(rèn)證碼(MAC)并最終交到傳輸層酱固;或?qū)⒔邮盏降臄?shù)據(jù)進(jìn)行解壓械念,解密,數(shù)據(jù)校驗(yàn)运悲,重新 組裝后傳到上一層龄减。

握手層協(xié)議(TLS Handshake Protocol)
握手層協(xié)議處于記錄層協(xié)議之上,握手層協(xié)議的作用是在真正的應(yīng)用數(shù)據(jù)傳輸之前班眯,使客戶端和服務(wù)器互相進(jìn)行身份認(rèn)證希停,協(xié)商加密算法以及生成加密密鑰。握手層用于協(xié)商出記錄層的參數(shù)署隘。這些參數(shù)將會(huì)被記錄層用于雙方的身份認(rèn)證宠能,實(shí)例化協(xié)商的安全參數(shù),錯(cuò)誤報(bào)告磁餐。

TLS在協(xié)議棧中的位置:

TLS的協(xié)議棧位置

TLS的握手過程

  1. 客戶端發(fā)送ClientHello消息违崇,包含可選密碼組件,一個(gè)客戶端生成的隨機(jī)數(shù)等诊霹,服務(wù)端接收后回一個(gè)ServerHello消息給客戶端羞延,確定密碼方案,并生成一個(gè)服務(wù)器隨機(jī)數(shù)脾还,發(fā)給客戶端伴箩。
    這一步的數(shù)據(jù)傳輸在TCP上進(jìn)行,數(shù)據(jù)都是公開的鄙漏,中間人攻擊者可以很輕松的得到這些數(shù)據(jù)嗤谚。
  2. 服務(wù)器發(fā)送證書棺蛛,服務(wù)器的身份確認(rèn)成功后;服務(wù)器可能會(huì)請求一個(gè)客戶端證書呵恢,要求客戶端進(jìn)行身份認(rèn)證鞠值,客戶端給服務(wù)器發(fā)出證書,驗(yàn)明身份渗钉。這一步不是必須的彤恶。
  3. 客戶端向服務(wù)器發(fā)出摘要認(rèn)證,確認(rèn)接收的消息的完整性鳄橘,保證沒有被第三方篡改声离。
  4. 雙方交換必需的加密參數(shù)。其中包括一個(gè)預(yù)主密鑰瘫怜,客戶端會(huì)用服務(wù)器證書中的公鑰將這個(gè)密鑰加密傳給服務(wù)器术徊,服務(wù)器使用私鑰進(jìn)行解密。
  5. 客戶端生成一個(gè)預(yù)主密鑰鲸湃,并使用服務(wù)器證書中的公鑰加密赠涮,服務(wù)器解密后生成一個(gè)主密鑰。雙方使用這個(gè)主密鑰(master secret)對(duì)應(yīng)用層數(shù)據(jù)進(jìn)行對(duì)稱加密(如AES256)暗挑。 主密鑰是客戶端和服務(wù)器共享的笋除。
  6. 最后,把這些準(zhǔn)備好的的安全參數(shù)交給記錄層協(xié)議炸裆。

下圖轉(zhuǎn)自維基百科TLS詞條 https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0

SSL_handshake_with_two_way_authentication_with_certificates.png

會(huì)話恢復(fù)過程
客戶端服務(wù)器出于性能的考慮垃它,可能會(huì)恢復(fù)前面的會(huì)話,或復(fù)制一個(gè)當(dāng)前存在的會(huì)話烹看,而不是重新協(xié)商密碼參數(shù)国拇,建立新的會(huì)話(4.2部分使用tcpdump跟蹤發(fā)現(xiàn),這個(gè)過程確實(shí)是耗時(shí)占比很大)惯殊。

  1. 客戶端發(fā)出一個(gè)ClientHello消息酱吝,這個(gè)消息包含要恢復(fù)的會(huì)話的Session ID。
  2. 服務(wù)接到這個(gè)SessionID后靠胜,檢查它的緩存是否存在該會(huì)話ID掉瞳。如果找到了,服務(wù)器將使用該會(huì)話狀態(tài)重建連接浪漠,并發(fā)一個(gè)ServerHello給客戶端,其中包含一個(gè)和ClientHello消息一模一樣的SessionID霎褐。
  3. 此時(shí)址愿,協(xié)議規(guī)定,必須要雙方發(fā)出ChangeCipherSpec消息冻璃,并接著發(fā)出Finished消息確認(rèn)握手完成响谓。然后客戶端服務(wù)器就可以傳輸應(yīng)用層數(shù)據(jù)了损合。
  4. 如果服務(wù)器沒有在緩存中找到Session ID,那么新的SessionID將會(huì)建立娘纷,然后又會(huì)執(zhí)行一次完全握手嫁审。

2 使用nginx搭建https服務(wù)器
2.1 環(huán)境準(zhǔn)備

先搭建nginx,nginx的搭建在官網(wǎng)中可以找到 http://nginx.org/en/docs/install.html
注意如果是用源碼編譯赖晶,有的較老版本構(gòu)建編譯時(shí)需要帶上參數(shù)--with-http_ssl_module律适,最新的nginx版本是默認(rèn)有這個(gè)編譯參數(shù)的。

配置

       server {
             listen 443 ssl;
             server_name somehost;
             ssl_certificate $somehost.crt;
             ssl_certificate_key $somehost.key;
             ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
             ssl_ciphers HIGH:!aNULL:!MD5;
             ...
       }

** ssl_certificate** : 存放服務(wù)器證書的地址遏插,主要用于數(shù)字證書的身份認(rèn)證捂贿。所有連到服務(wù)器的客戶端都能拿到這個(gè)證書;
*** ssl_certificate_key*** : 是私鑰胳嘲,只能被服務(wù)器知道厂僧。

ssl_protocols, ssl_ciphers選項(xiàng)是可選的了牛。

2.2 詳細(xì)操作步驟

下面嘗試在本地搭建一個(gè)簡單的https服務(wù)器颜屠,在443端口監(jiān)聽。

步驟如下

  1. 搭建一個(gè)nginx服務(wù)器鹰祸;
  2. 使用openssl生成服務(wù)器私鑰甫窟,客戶端私鑰,服務(wù)器公鑰福荸,客戶端公鑰蕴坪;
  3. 生成CA根證書,為服務(wù)器證書和客戶端證書(可選)提供簽名服務(wù);
  4. 生成服務(wù)器證書和客戶端證書敬锐,并請求CA的簽名背传;
  5. 在操作系統(tǒng)上信任我們偽造的服務(wù)器證書,這里沒有為客戶端生成證書台夺;
  6. 隨便寫一個(gè)web服務(wù)径玖,提供一個(gè)url返回一段靜態(tài)報(bào)文,讓nginx為它做一下代理颤介,然后啟動(dòng)這個(gè)web服務(wù)器梳星;
  7. 測試。

以下是這些步驟的操作命令

****生成服務(wù)端私鑰****:
$ openssl genrsa -out server.key 2048
****生成服務(wù)端公鑰****:
$ openssl rsa -in server.key -pubout -out server.pem
****生成客戶端私鑰****:
$ openssl genrsa -out client.key 2048
****生成客戶端公鑰****:
$ openssl rsa -in client.key -pubout -out client.pem
****生成CA證書****:

 $ openssl genrsa -out ca.key 2048
 $ openssl req -new -key ca.key -out ca.csr
 $ openssl x509 -req -in ca.csr -signkey ca.key -out  ca.crt

生成客戶端服務(wù)端證書
服務(wù)端:
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
客戶端:
$ openssl req -new -key client.key -out client.csr
向CA申請簽名:
$ openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

證書和私鑰生成完畢后滚朵,開始配置nginx(http部分從略)冤灾;

      #HTTPS server
      server {
              listen       443 ssl;
              server_name  localhost;
              ssl_certificate      ../ssl/certs/server.crt;  #放置服務(wù)器證書的目錄
              ssl_certificate_key  ../ssl/private/server.key;  #放置服務(wù)器私鑰的目錄
              ssl_session_cache    shared:SSL:1m;
              ssl_session_timeout  5m;
              ssl_ciphers  HIGH:!aNULL:!MD5;
              ssl_prefer_server_ciphers  on;
              location / {
                     proxy_pass   http://127.0.0.1:8887;
                     proxy_set_header Host $host;
                     proxy_set_header X-Real-IP $remote_addr;
              }
       }

配置完后,保存辕近,在nginx根目錄下運(yùn)行命令:
$ ./sbin/nginx -t -c conf/https_server.conf
nginx會(huì)測試一下配置文件 conf/https_server.conf
如果輸出下面的東西韵吨,表示配置沒什么格式問題了:

啟動(dòng)nginx:
$ ./sbin/nginx -c conf/https_server.conf
這里我們搭建一個(gè)http服務(wù)器,在端口8887上監(jiān)聽移宅,使用nginx代理归粉,在瀏覽器中訪問:
https://localhost/hello
返回:

       {
              "user_id":1, "name":"Tom"
       }   
2.3 信任證書:

瀏覽器中輸入
https://localhost:443
因?yàn)槲覀兊母C書是自己簽發(fā)的椿疗,簽發(fā)機(jī)構(gòu)是偽造的,不在瀏覽器的信任列表中糠悼。對(duì)于這種情況届榄,不同的瀏覽器對(duì)此會(huì)有不同的表現(xiàn),但主流的瀏覽器都會(huì)發(fā)出警告倔喂。下面提供了一種辦法铝条,使瀏覽器信任證書。注意滴劲,這里只是為了測試攻晒,正常上網(wǎng)不要忽略瀏覽器的警告,輕易地信任不明來源的證書班挖。

下面是在Mac下的Google Chrome中信任證書的操作步驟:
. 當(dāng)瀏覽器提示連接不安全時(shí)鲁捏,在瀏覽器的抓包工具中點(diǎn)到如下的界面:

圖4

. 點(diǎn)按鈕:View Certificate
. 拖動(dòng)證書的icon,拉到本地桌面上并雙擊它:

圖5:訪問https://www.baidu.com得到的服務(wù)器證書萧芙,僅舉例

雙擊它打開系統(tǒng)的鑰匙串给梅,將桌面證書拖拽到系統(tǒng)鑰匙串中,
雙擊打開双揪,選擇『始終信任』

圖6

圖7

注:截圖的證書為測試時(shí)隨意生成的根證書动羽;所有證書信任的辦法類似。

重啟瀏覽器后渔期,再訪問https://localhost/hello 运吓,會(huì)看到這樣的結(jié)果:

圖8
2.4 測試加密效果

現(xiàn)在,我們嘗試用抓包工具模擬中間人截取報(bào)文疯趟,看看能不能截取到報(bào)文:

在mac上我們使用charles進(jìn)行抓包拘哨,結(jié)果如下,報(bào)文已經(jīng)被加密信峻,看到的內(nèi)容都是亂碼:

圖9

嘗試用Charles進(jìn)行一次中間人攻擊:偽造證書倦青,在Charles上可以安全一個(gè)代理證書,具體操作參考這里:http://www.reibang.com/p/7a88617ce80b
盹舞,然后再訪問https://localhost/hello

這時(shí)瀏覽器會(huì)又提示我們連接不安全产镐,這是因?yàn)門LS握手感知到了客戶端的證書來源不明,假如我們點(diǎn)擊高級(jí)踢步,繼續(xù)訪問癣亚,忽略這個(gè)警告,那么我們會(huì)在抓包工具上看到這樣的畫面:

圖10

報(bào)文的內(nèi)容成功被Charles竊聽了获印,所以逃糟,再次驗(yàn)證了一點(diǎn):如果正常上網(wǎng)瀏覽網(wǎng)頁,操作電子銀行等敏感信息時(shí)蓬豁,不要隨便忽略瀏覽器的安全警告绰咽。

由于大多數(shù)人安全意識(shí)薄弱,很習(xí)慣地點(diǎn)繼續(xù)訪問不安全連接 地粪,所以就有了HSTS取募。

2.5 HSTS是什么

****  HSTS(HTTP Strict Transport Security)****,這是一個(gè)由IEEE發(fā)布的網(wǎng)絡(luò)安全策略機(jī)制蟆技,如果服務(wù)器增加了這種策略玩敏,那么就意味著要求客戶端必須使用https協(xié)議和服務(wù)器進(jìn)行對(duì)話。
  主流的瀏覽器都實(shí)現(xiàn)了HSTS策略质礼。當(dāng)TLS握手出現(xiàn)問題時(shí)旺聚,瀏覽器不會(huì)再訪問服務(wù)器。
  百度的防火墻代理就實(shí)現(xiàn)了這個(gè)策略眶蕉。訪問https://www.baidu.com 砰粹,在瀏覽器截取到的服務(wù)器響應(yīng)頭中有一個(gè)Strict-Transport-Security字段 max-age=172800 。max-age是指HSTS的失效時(shí)間造挽,單位是秒碱璃。

圖11

由于服務(wù)器響應(yīng)頭增加了這個(gè)字段,瀏覽器就會(huì)履行一些HSTS的職責(zé)饭入。假如我們采取抓包工具偽造一個(gè)未知證書嵌器,再去訪問域名,就會(huì)受到警告谐丢,嘗試讓瀏覽器忽略不安全的警告繼續(xù)訪問會(huì)被禁止爽航,如下圖:

圖12

然而HSTS也不是絕對(duì)安全的。一方面原因在于Strict-Transport-Security的max-age會(huì)過期乾忱,瀏覽器是否強(qiáng)制HSTS策略取決于當(dāng)前系統(tǒng)時(shí)間讥珍,它可能偽造;另一方面是因?yàn)槭状卧L問網(wǎng)址并不受HSTS保護(hù)饭耳〈觯可見技術(shù)對(duì)安全的防護(hù)永遠(yuǎn)是有限的,還需要用戶有足夠的安全意識(shí)進(jìn)行自我保護(hù)寞肖。

3 實(shí)現(xiàn)https抓包

了解了https的原理之后纲酗,知道TLS的握手關(guān)鍵在身份認(rèn)證這一步。HTTPS的數(shù)據(jù)傳輸可以類比成交談的雙方各自亮出身份證新蟆,然后用約定的暗號(hào)進(jìn)行交流觅赊,這樣即時(shí)旁邊有人竊聽,也無法破解經(jīng)過加密的信息琼稻。

測試時(shí)吮螺,通常會(huì)有抓取https包的需求。如果以為https已被加密,我們沒辦法抓到明文包鸠补,那這是不對(duì)的萝风。抓包的原理通常是在通信雙方插一個(gè)中間代理,對(duì)原有的客戶端和服務(wù)器的請求進(jìn)行來回轉(zhuǎn)發(fā)紫岩。如果要抓取https包规惰,顯然,構(gòu)造的代理必須有完成TLS握手的能力泉蝌,所以代理工具一般需要支持ssl歇万。有了TLS的握手能力,我們再設(shè)法使通信雙方相信代理的身份勋陪,就能實(shí)現(xiàn)https的抓包了叽讳∽偶ⅲ可以看到芦岂,https的數(shù)據(jù)安全關(guān)鍵點(diǎn)其實(shí)就是在數(shù)字證書上 拴测,因此也很容易理解為什么主流的瀏覽器都會(huì)警告用戶使用了來路不明的機(jī)構(gòu)頒發(fā)的證書。

實(shí)現(xiàn)https抓包呻粹,具體操作方案就是:用一個(gè)支持ssl的代理壕曼,偽造一個(gè)ca證書,當(dāng)通信雙方在TLS握手時(shí)發(fā)現(xiàn)有人竊聽時(shí)等浊,設(shè)法讓他們相信代理的身份(這個(gè)過程就見2.3); 代理身份被信任了腮郊,就會(huì)發(fā)生這個(gè)過程: 客戶端和代理進(jìn)行握手,請求數(shù)據(jù)發(fā)到代理上筹燕,由代理和服務(wù)器做TLS握手轧飞,并轉(zhuǎn)傳客戶端的請求數(shù)據(jù);服務(wù)器加密報(bào)文應(yīng)答撒踪,代理解密報(bào)文再用和客戶端協(xié)商的密碼方案加密報(bào)文过咬,傳給客戶端,客戶端解密報(bào)文制妄。

Charles抓包參看:http://www.reibang.com/p/7a88617ce80b


4 HTTPS的性能
4.1 HTTPS與HTTP的性能評(píng)測對(duì)比

我們使用Jmeter來測試http和https的比較掸绞。
在遠(yuǎn)程服務(wù)器上搭建一個(gè)http服務(wù)器,讓它返回一個(gè)簡單的靜態(tài)網(wǎng)頁:

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8">
            <title>首頁測試</title>
      </head><body>
      <p>這是一個(gè)測試網(wǎng)頁</p>

然后使用nginx進(jìn)行代理
第一次關(guān)閉nginx的ssl安全開關(guān)耕捞,讓服務(wù)器作為普通的http服務(wù)器衔掸,用jmeter發(fā)請求;第二次俺抽,開啟ssl策略敞映,強(qiáng)制進(jìn)行TLS握手,再用jmeter發(fā)請求磷斧。

兩次的數(shù)據(jù)比較如下

請求方式 響應(yīng)時(shí)間(ms)
http 164
https 419

100個(gè)樣本的測試數(shù)據(jù)
http100個(gè)樣本的數(shù)據(jù):

圖13

https100個(gè)樣本的數(shù)據(jù):

圖14

注意:
. 使用jmeter發(fā)出100個(gè)樣本時(shí)振愿,需要把keep-alive選項(xiàng)勾掉捷犹,保證每次請求都進(jìn)行了TCP握手,而不是復(fù)用連接冕末;否則得到的性能數(shù)據(jù)會(huì)更好萍歉。
. 發(fā)出https請求時(shí),除了在服務(wù)端nginx上把ssl的開關(guān)打開栓霜,還要在jmeter的協(xié)議選項(xiàng)中填上https翠桦,如圖:


圖15

可以看到,使用了https胳蛮,如果每次連接都進(jìn)行完全握手,https的性能會(huì)比http多出250ms左右丛晌。也就是說仅炊,請求一個(gè)動(dòng)態(tài)網(wǎng)頁的響應(yīng)時(shí)間假如是200ms,那么https會(huì)使性能下降100%澎蛛。然而抚垄,如果使用keep-alive連接復(fù)用,性能的對(duì)比并沒有那么可怕:
使用keep-alive谋逻,100個(gè)https的請求的結(jié)果:

圖16

http

圖17

除了第一個(gè)樣本的差距比較大呆馁,整個(gè)平均響應(yīng)時(shí)間看上去https反而要略優(yōu)于http。
下面嘗試使用tcpdump探查一下TLS握手各個(gè)階段的耗時(shí)分布


4.2 TLS握手的性能評(píng)測
4.2.1數(shù)據(jù)包截取

這里使用tcpdump來抓一段https請求的數(shù)據(jù)包(這里并沒有發(fā)生TLS完全握手毁兆,客戶端沒有給服務(wù)器傳證書):

輸入命令:
$ sudo tcpdump host $hostname
然后請求一下https的url浙滤,會(huì)截獲到如下的數(shù)據(jù):

Line 1 15:19:48.793920 IP client.https.host.63209 > server.httpshost: Flags [S], seq 2411985045, win 65535, options [mss 1460,nop,wscale   5,nop,nop,TS val 669725535 ecr 0,sackOK,eol], length 0
Line 2 15:19:48.875001 IP server.httpshost > client.https.host.63209: Flags [S.], seq 284701943, ack 2411985046, win 14480, options [mss 1460,sackOK,TS val 175414051 ecr 669725535,nop,wscale 8], length 0
Line 3 15:19:48.875074 IP client.https.host.63209 > server.httpshost: Flags [.], ack 1, win 4117, options [nop,nop,TS val 669725616 ecr 175414051], length 0
Line 4 15:19:48.876925 IP client.https.host.63209 > server.httpshost: Flags [P.], seq 1:201, ack 1, win 4117, options [nop,nop,TS val 669725617 ecr 175414051], length 200
Line 5 15:19:48.958843 IP server.httpshost > client.https.host.63209: Flags [.], ack 201, win 61, options [nop,nop,TS val 175414134 ecr 669725617], length 0
Line 6 15:19:48.961690 IP server.httpshost > client.https.host.63209: Flags [.], seq 1:1449, ack 201, win 61, options [nop,nop,TS val 175414135 ecr 669725617], length 1448
Line 7 15:19:48.961696 IP server.httpshost > client.https.host.63209: Flags [.], seq 1449:2897, ack 201, win 61, options [nop,nop,TS val 175414135 ecr 669725617], length 1448
Line 8 15:19:48.961736 IP client.https.host.63209 > server.httpshost: Flags [.], ack 2897, win 4027, options [nop,nop,TS val 669725700 ecr 175414135], length 0
Line 9 15:19:48.961914 IP server.httpshost > client.https.host.63209: Flags [P.], seq 2897:3255, ack 201, win 61, options [nop,nop,TS val 175414135 ecr 669725617], length 358
Line 10 15:19:48.961933 IP client.https.host.63209 > server.httpshost: Flags [.], ack 3255, win 4016, options [nop,nop,TS val 669725700 ecr 175414135], length 0
Line 11 15:19:48.964670 IP client.https.host.63209 > server.httpshost: Flags [P.], seq 201:276, ack 3255, win 4096, options [nop,nop,TS val 669725702 ecr 175414135], length 75
Line 12 15:19:49.045770 IP server.httpshost > client.https.host.63209: Flags [.], ack 276, win 61, options [nop,nop,TS val 175414221 ecr 669725702], length 0
Line 13 15:19:49.045812 IP client.https.host.63209 > server.httpshost: Flags [P.], seq 276:327, ack 3255, win 4096, options [nop,nop,TS val 669725783 ecr 175414221], length 51
Line 14 15:19:49.126510 IP server.httpshost > client.https.host.63209: Flags [.], ack 327, win 61, options [nop,nop,TS val 175414302 ecr 669725783], length 0
Line 15 15:19:49.126517 IP server.httpshost > client.https.host.63209: Flags [P.], seq 3255:3306, ack 327, win 61, options [nop,nop,TS val 175414302 ecr 669725783], length 51
Line 16 15:19:49.126575 IP client.https.host.63209 > server.httpshost: Flags [.], ack 3306, win 4094, options [nop,nop,TS val 669725862 ecr 175414302], length 0
Line 17 15:19:49.127304 IP client.https.host.63209 > server.httpshost: Flags [P.], seq 327:471, ack 3306, win 4096, options [nop,nop,TS val 669725862 ecr 175414302], length 144
Line 18 15:19:49.208120 IP server.httpshost > client.https.host.63209: Flags [.], ack 471, win 65, options [nop,nop,TS val 175414384 ecr 669725862], length 0
Line 19 15:19:49.209352 IP server.httpshost > client.https.host.63209: Flags [P.], seq 3306:3671, ack 471, win 65, options [nop,nop,TS val 175414385 ecr 669725862], length 365
Line 20 15:19:49.209394 IP client.https.host.63209 > server.httpshost: Flags [.], ack 3671, win 4084, options [nop,nop,TS val 669725943 ecr 175414385], length 0
Line 21 15:19:49.210228 IP client.https.host.63209 > server.httpshost: Flags [P.], seq 471:502, ack 3671, win 4096, options [nop,nop,TS val 669725943 ecr 175414385], length 31
Line 22 15:19:49.210263 IP client.https.host.63209 > server.httpshost: Flags [F.], seq 502, ack 3671, win 4096, options [nop,nop,TS val 669725943 ecr 175414385], length 0
Line 23 15:19:49.292232 IP server.httpshost > client.https.host.63209: Flags [.], ack 502, win 65, options [nop,nop,TS val 175414467 ecr 669725943], length 0
Line 24 15:19:49.292239 IP server.httpshost > client.https.host.63209: Flags [F.], seq 3671, ack 502, win 65, options [nop,nop,TS val 175414467 ecr 669725943], length 0
Line 25 15:19:49.292240 IP server.httpshost > client.https.host.63209: Flags [.], ack 503, win 65, options [nop,nop,TS val 175414467 ecr 669725943], length 0
Line 26 15:19:49.292286 IP client.https.host.63209 > server.httpshost: Flags [F.], seq 502, ack 3672, win 4096, options [nop,nop,TS val 669726025 ecr 175414467], length 0
4.2.2抓包數(shù)據(jù)解析
  • Line1-Line3 是TCP的3路握手,這里耗時(shí)從15:19:48.793920到15:19:48.875074 這一次RTT花費(fèi)了81.154ms
  • Line4-Line5 判斷是客戶端發(fā)ClientHello消息气堕,這里客戶端發(fā)出了200字節(jié)纺腊,TLS握手的開始
    *Line7 Line8 Line9 從TCP選項(xiàng)可以看出來,是數(shù)據(jù)分了三組傳送茎芭,總字節(jié)是1448 * 2 + 358 = 3254個(gè)字節(jié)揖膜,由TLS協(xié)議可以判斷這是服務(wù)器在回應(yīng)ServerHello以及傳遞服務(wù)器證書;這個(gè)過程耗時(shí)是89.968 ms;與一次TCP握手耗時(shí)相近
  • Line10到Line16 是客戶端和服務(wù)器協(xié)商密鑰的過程梅桩。這期間壹粟,客戶端發(fā)送了兩次數(shù)據(jù),服務(wù)器發(fā)了一次宿百;服務(wù)器進(jìn)行了兩次非對(duì)稱解密運(yùn)算趁仙,一次數(shù)字簽名校驗(yàn),一次解密拿到隨機(jī)預(yù)主密鑰犀呼,總共耗時(shí)161.905ms幸撕,到Line16 TLS 握手完成
  • Line17行~Line22開始進(jìn)行應(yīng)用數(shù)據(jù)傳輸,傳輸時(shí)使用預(yù)主密鑰計(jì)算出來的主密鑰對(duì)應(yīng)用層數(shù)據(jù)進(jìn)行加密外臂,總共耗時(shí)82.959ms
  • 最后4行是TCP的關(guān)閉過程坐儿,可以暫不考慮。
4.2.3 TLS性能結(jié)果匯總

從4.2.2 的分析可以看到整個(gè)過程400多ms的時(shí)間分配如下:

過程 耗時(shí)/ms 耗時(shí)占比%
tcp握手 81.154ms 19.49
傳遞證書和ClientHello,ServerHello 89.968ms 21.61
協(xié)商主密鑰和簽名校驗(yàn)(2次公鑰加密/解密運(yùn)算) 161.905ms 38.89
應(yīng)用層數(shù)據(jù)傳輸 82.959ms 19.93
其他 0.357ms 0.08
總耗時(shí)(Line22時(shí)間減去Line1) 416.343ms 19.49

進(jìn)行過充分優(yōu)化的https連接主要的耗時(shí)基本上集中在應(yīng)用層數(shù)據(jù)傳輸上,這跟我們使用Jmeter評(píng)測keep-alive狀態(tài)得到的數(shù)據(jù)相吻合貌矿。

從表中可見炭菌,HTTPS完全握手下性能消耗大多集中在TLS握手期間,約占60%逛漫。TLS握手中服務(wù)器進(jìn)行RSA解密不僅會(huì)有時(shí)間消耗黑低,還會(huì)對(duì)服務(wù)器形成CPU壓力。

通過這個(gè)分析酌毡,可以看出HTTPS的性能優(yōu)化策略應(yīng)該會(huì)從嘗試考慮減少TLS握手頻率克握,復(fù)用TLS會(huì)話,在分布式服務(wù)中用緩存共享會(huì)話枷踏,或?qū)⒔饷苓\(yùn)算轉(zhuǎn)到云端菩暗,提升服務(wù)器的硬件級(jí)別等方面入手。

附1:密碼學(xué)相關(guān)概念:

主密鑰(master secret):一個(gè)48位的共享密鑰旭蠕,客戶端和服務(wù)器都會(huì)知道停团。
MAC算法: 消息認(rèn)證碼算法。
對(duì)稱密鑰加密:加密和解密編碼使用的密鑰相同掏熬。對(duì)稱加密的缺點(diǎn)之一是任何兩臺(tái)主機(jī)進(jìn)行通信都需要維護(hù)一個(gè)雙方都知道的密鑰佑稠,造成管理負(fù)擔(dān),一個(gè)有N個(gè)站點(diǎn)的網(wǎng)絡(luò)旗芬,可能需要維護(hù) N(N-1)個(gè)密鑰舌胶。
流加密:是一種對(duì)稱加密算法,加密和解密雙方使用相同偽隨機(jī)加密數(shù)據(jù)流(pseudo-random stream)作為密鑰岗屏,明文數(shù)據(jù)每次與密鑰數(shù)據(jù)流順次對(duì)應(yīng)加密辆琅,得到密文數(shù)據(jù)流。
分組加密:又稱分塊加密或塊密碼这刷,是一種對(duì)稱密鑰算法婉烟。它將明文分成多個(gè)等長的模塊(block),使用確定的算法和對(duì)稱密鑰對(duì)每組分別加密解密暇屋。如AES似袁,DES
公鑰加密:非對(duì)稱加密。加密和解密使用不同的密鑰咐刨,加密密鑰是公開的昙衅,解密密鑰一般被服務(wù)器保存,不對(duì)外公布定鸟。
數(shù)字簽名:附在報(bào)文中的特殊加密校驗(yàn)碼而涉,用來證明報(bào)文作者的身份。
數(shù)字證書:類似與身份ID联予,常用的數(shù)字證書格式是X.509 v3啼县,證書中包含基本的字段信息:序列號(hào)材原,簽名算法ID,證書頒發(fā)機(jī)構(gòu)季眷,有效期余蟹,對(duì)象名稱,對(duì)象公開密鑰信息子刮,發(fā)布者的唯一ID威酒,對(duì)象的唯一ID,擴(kuò)展挺峡。
PKI: Public Key Infrastructure 公鑰基礎(chǔ)設(shè)施葵孤,是一組由硬件、軟件沙郭、參與者佛呻、管理政策與流程組成的基礎(chǔ)架構(gòu),其目的在于創(chuàng)造病线、管理、分配鲤嫡、使用送挑、存儲(chǔ)以及撤銷數(shù)字證書。

附2:參考資料

說明: 本文關(guān)于TLS協(xié)議的描述本于RFC5246暖眼,Nginx搭建https本于nginx的官網(wǎng)文檔

  1. RFC5246參考網(wǎng)址: https://tools.ietf.org/html/rfc5246
  2. Nginx安裝參考網(wǎng)址:http://nginx.org/en/docs/install.html
  3. Nginx搭建https參考網(wǎng)址: http://nginx.org/en/docs/http/configuring_https_servers.html
  4. 信任證書方案本文只是在MAC系統(tǒng)上進(jìn)行了操作實(shí)踐惕耕,其他操作系統(tǒng)可參考 : http://blog.getpostman.com/2014/01/28/using-self-signed-certificates-with-postman/

附3:使用charles進(jìn)行https抓包

也是我寫的一篇文章:http://www.reibang.com/p/7a88617ce80b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诫肠,隨后出現(xiàn)的幾起案子司澎,更是在濱河造成了極大的恐慌,老刑警劉巖栋豫,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挤安,死亡現(xiàn)場離奇詭異,居然都是意外死亡丧鸯,警方通過查閱死者的電腦和手機(jī)蛤铜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丛肢,“玉大人围肥,你說我怎么就攤上這事》湓酰” “怎么了穆刻?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杠步。 經(jīng)常有香客問我氢伟,道長榜轿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任腐芍,我火速辦了婚禮差导,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猪勇。我一直安慰自己设褐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布泣刹。 她就那樣靜靜地躺著助析,像睡著了一般。 火紅的嫁衣襯著肌膚如雪椅您。 梳的紋絲不亂的頭發(fā)上外冀,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音掀泳,去河邊找鬼雪隧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛员舵,可吹牛的內(nèi)容都是我干的脑沿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼马僻,長吁一口氣:“原來是場噩夢啊……” “哼庄拇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起韭邓,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤措近,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后女淑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞭郑,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年诗力,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凰浮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苇本,死狀恐怖袜茧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓣窄,我是刑警寧澤笛厦,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站俺夕,受9級(jí)特大地震影響裳凸,放射性物質(zhì)發(fā)生泄漏贱鄙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一姨谷、第九天 我趴在偏房一處隱蔽的房頂上張望逗宁。 院中可真熱鬧,春花似錦梦湘、人聲如沸瞎颗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哼拔。三九已至,卻和暖如春瓣颅,著一層夾襖步出監(jiān)牢的瞬間倦逐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工宫补, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留檬姥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓粉怕,卻偏偏與公主長得像穿铆,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斋荞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容