詳解HTTPS 的原理和 NodeJS 的實現(xiàn)
基本原理
HTTP協(xié)議采用明文傳輸數(shù)據(jù),當(dāng)涉及敏感信息的傳送時,極有可能會受到竊聽或者中間人的攻擊。HTTPS是HTTP與SSL/TLS的組合,即使用加密通訊以及網(wǎng)絡(luò)服務(wù)器的身份鑒定來進(jìn)行信息的安全傳輸。其核心有二:
- 使用證書對服務(wù)器及請求端的身份驗證
- 使用一組對稱秘鑰加密包括請求頭在內(nèi)的所有信息傳輸
握手流程
HTTPS鏈接的建立過程中涉及到服務(wù)器端證書、客戶端證書(可選)、服務(wù)器端的非對稱秘鑰以及后續(xù)通信過程中使用的對稱秘鑰幾個內(nèi)容。
- 客戶端對HTTPS的地址發(fā)出請求,并且將自己的SSL版本號等信息發(fā)送給服務(wù)器
- 服務(wù)器接收到請求,將服務(wù)器證書和公鑰等信息返回給客戶端
- 客戶端接收到證書后向證書頒發(fā)機(jī)構(gòu)驗證證書的合法性。如果證書不合法(比如自行簽發(fā)的證書),則向用戶發(fā)出警告并確認(rèn)是否繼續(xù),用戶可以選擇在此時離開終止HTTPS的鏈接。
- 證書合法或客戶端確認(rèn)在不安全的情況下繼續(xù),客戶端生成pre-master secret并且使用2中收到的服務(wù)器公鑰加密后發(fā)送給服務(wù)器。如果是使用交互策略的TLS,則同時需要將客戶端的證書發(fā)送給服務(wù)器。服務(wù)器檢查客戶端的證書頒發(fā)機(jī)構(gòu)是否在信任列表中,以及證書內(nèi)容是否合法。若不合法,結(jié)束本次會話。
- 服務(wù)器使用私鑰解密pre-master secret,然后雙方通過一種實現(xiàn)商定好的加密算法生成本次通訊使用的master secret。
- 雙方互相通知對方本次SSL握手成功,其后均使用master secret對傳輸內(nèi)容進(jìn)行加密。
下圖簡要的說明了這個流程的實現(xiàn)。
一開始我也心存疑問:為什么要單獨使用另外一組對稱秘鑰來實現(xiàn)對信息的加密而不直接使用服務(wù)器和客戶端雙方的非對稱秘鑰呢?我自身非常認(rèn)同下面這個回答的解釋:
傳輸過程使用對稱密鑰是因為對稱加密比非對稱加密的運算量低一個數(shù)量級以上,所以這樣的方式可以提高雙方會話的運算速度。
對于加密算法不是非常了解,希望大牛指點一二。
Openssl自簽名證書的生成
HTTPS中一個關(guān)鍵就是證書文件。當(dāng)然我們可以找專業(yè)的第三方機(jī)構(gòu)簽發(fā)。自己玩玩的話就用自簽名的證書就可以了,用戶在訪問的時候則需要確認(rèn)安全性問題。 1、生成傳輸pre-master secret的時候所需要的Server端的私鑰,運行時提示需要輸入密碼,用于對key的加密。以后每次讀取此文件的時候,都需要輸入指令。
# 生成服務(wù)器端的非對稱秘鑰 openssl genrsa -des3 -out server.key 1024 # 生成簽名請求的CSR文件 openssl req -new -key server.key -out server.csr # 自己對證書進(jìn)行簽名,簽名的有效期是365天 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt # 去除證書文件的password cp server.key server.key.orig openssl rsa -in server.key.orig -out server.key
最終在建立HTTPS鏈接中使用的文件是
- server.crt
- server.key
NodeJS建立一個HTTPS的Server
var httpsModule = require('https'); var fs = require('fs'); var https = httpsModule.Server({ key: fs.readFileSync('/path/to/server.key'), cert: fs.readFileSync('/path/to/server.crt') }, function(req, res){ res.writeHead(200); res.end("hello world\n"); }); //https默認(rèn)de監(jiān)聽端口時443,啟動1000以下的端口時需要sudo權(quán)限 https.listen(443, function(err){ console.log("https listening on port: 443"); });
這里使用的fs.readFileSync方法會阻塞其他進(jìn)程直到文件的讀取完畢,在讀取關(guān)鍵的配置文件的時候這樣的方法是比較適宜的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node.js數(shù)據(jù)庫操作之查詢MySQL數(shù)據(jù)庫(二)
這篇文章主要介紹了Node.js數(shù)據(jù)庫操作之查詢MySQL數(shù)據(jù)庫的相關(guān)資料,文中介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用mysql能帶來一定的幫助,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03Node.JS獲取GET,POST數(shù)據(jù)之queryString模塊使用方法詳解
本文將詳細(xì)介紹nodeJS中的queryString模塊使用方法,包括Node.JS獲取GET,POST數(shù)據(jù)的方法,需要的朋友可以參考下2020-02-02node.js中對Event Loop事件循環(huán)的理解與應(yīng)用實例分析
這篇文章主要介紹了node.js中對Event Loop事件循環(huán)的理解與應(yīng)用,結(jié)合實例形式分析了node.js中Event Loop事件循環(huán)相關(guān)原理、使用方法及操作注意事項,需要的朋友可以參考下2020-02-02使用Node.js腳本自動統(tǒng)計代碼量的實現(xiàn)代碼
手動統(tǒng)計代碼行數(shù)通常會耗費大量時間和精力,為了提高統(tǒng)計效率并減少人為錯誤,我們可以借助自動化工具來完成這項任務(wù),本文將介紹如何使用 Node.js 腳本來自動化統(tǒng)計項目代碼行數(shù),讓我們能夠輕松快捷地獲取項目的代碼量信息,需要的朋友可以參考下2023-12-12