摘要:使用約定好的計算握手消息,并使用生產(chǎn)的隨機(jī)數(shù)對消息進(jìn)行加密,最后將之前生成的所有消息發(fā)送給網(wǎng)站。之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對稱加密算法進(jìn)行加密。支持四個異步事件。
由于HTTP沒有加密機(jī)制,其傳輸?shù)膬?nèi)容很容易泄漏,并且HTTP協(xié)議沒法確認(rèn)通信方,也無法保證接收到的報文在傳輸過程中是否被篡改,因此HTTPS是在HTTP協(xié)議的基礎(chǔ)上提供了加密、認(rèn)證和完整性保護(hù)的功能。HTTPS并非是應(yīng)用層的一種新協(xié)議,只是HTTP通信接口部分用SSL和TLS協(xié)議代替而已,通常HTTP直接和傳輸層的TCP協(xié)議通信,當(dāng)使用了SSL后,HTTP先和SSL協(xié)議通信,SSL再和TCP協(xié)議通信。
加密方法近代的加密方法中加密算法是公開的,而密鑰卻是保密的,加密和解密都需要用到密鑰,沒有密鑰就沒法對加密內(nèi)容進(jìn)行解密,通過這種方式得以保持加密方法的安全性。加密和解密同用一個密鑰的方式陳為共享密鑰加密,也被稱為對稱密鑰加密。以共享密鑰方式的加密必須將密鑰也發(fā)給對方,在網(wǎng)絡(luò)上發(fā)送密鑰很容易被攻擊者獲取。并且服務(wù)器如果對所有客戶端都使用同樣的共享密鑰,無異于沒有加密,所以HTTPS采用生成的隨機(jī)數(shù)來作為共享加密算法的密鑰。
公開密鑰加密使用一對非對稱的密鑰,一把叫做私有密鑰,一把叫做公有密鑰,發(fā)送密文的一方使用對方的公開密鑰進(jìn)行加密處理,對方收到被加密的信息后,再使用自己的私有密鑰進(jìn)行解密,這樣就不用擔(dān)心密鑰被攻擊者獲取。
HTTPS采用共享密鑰加密和公開密鑰加密兩者并用的混合加密機(jī)制,如果僅僅保證密鑰的安全性,使用公開密鑰加密的方式就可以實(shí)現(xiàn)了,但是公開密鑰加密方式比共享密鑰加密,其處理速度要慢。所以HTTPS在交換密鑰環(huán)節(jié)采用公開密鑰加密方式,之后建立通信交換報文階段采用共享密鑰加密方式。
公開密鑰加密方式也不能保證公開密鑰本身的真實(shí)性,比如,在與某臺服務(wù)器建立連接時,無法保證接收到的公開密鑰就是需要連接的那個服務(wù)器的密鑰,這個時候可以采用數(shù)字證書認(rèn)證機(jī)構(gòu)和其相關(guān)機(jī)關(guān)頒發(fā)的公開密鑰證書。
HTTPS的握手過程首先,客戶端會發(fā)送一個https的請求,把自身支持的一系列密鑰算法組件(Cipher Suite)發(fā)送給服務(wù)器。
服務(wù)器接收到客戶端所有的Cipher后與自身支持的對比,如果不支持則連接斷開,反之則會從中選擇一種加密算法和HASH算法以證書的形式返回給客戶端,證書中包含了加密公鑰,頒證機(jī)構(gòu),網(wǎng)站地址,失效日期等等。
客戶端收到服務(wù)器端的響應(yīng)后會做以下幾件事:
1:驗(yàn)證證書的合法性,頒發(fā)證書的機(jī)構(gòu)是否合法與是否過期,證書中包含的網(wǎng)站地址是否與正在訪問的地址一致等,證書驗(yàn)證通過后,在瀏覽器的地址欄會加上一把小鎖。
2:證書驗(yàn)證通過后,生成隨機(jī)密碼,用證書中的公鑰加密。
3:使用約定好的HASH計算握手消息,并使用生產(chǎn)的隨機(jī)數(shù)對消息進(jìn)行加密,最后將之前生成的所有消息發(fā)送給網(wǎng)站。
服務(wù)器接收到客戶端傳來的密文,用自己的私鑰來解密取出隨機(jī)數(shù)密碼,然后用隨機(jī)數(shù)密碼解密瀏覽器發(fā)送過來的握手消息,并驗(yàn)證HASH是否是與瀏覽器發(fā)來的一致,然后使用密碼加密一段握手消息,發(fā)送給瀏覽器。
客戶端用隨機(jī)數(shù)解密并計算出握手消息的HASH,如果與服務(wù)器端發(fā)來的HASH一致,此時握手過程結(jié)束。
之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對稱加密算法進(jìn)行加密。因?yàn)檫@串密碼只有客戶端和服務(wù)器知道,所有即使中間請求被攔截也是沒法解密數(shù)據(jù)的,以此保證了通信的安全。
其中非對稱加密算法用于在握手消息過程中加密生成的隨機(jī)數(shù)密碼,對稱加密算法用于對真正傳輸?shù)臄?shù)據(jù)進(jìn)行加密,而HASH算法用于驗(yàn)證數(shù)據(jù)的完整性,TLS握手過程中如果有任何錯誤,都會使加密連接斷開,從而阻止了隱私信息的傳輸,由于HTTPS非常的安全,攻擊者無法從中找到下手的地方,于是更多的是采用了假證書的手法來欺騙客戶端,從而獲取明文的信息。
瀏覽器在對證書進(jìn)行驗(yàn)證時,以下幾種情況會導(dǎo)致驗(yàn)證失?。?/p>
SSL證書不是由受信任的CA機(jī)構(gòu)頒發(fā)的
證書過期
訪問的網(wǎng)站域名與證書綁定的域名不一致
對HTTPS最常見的攻擊手段就是SSL證書欺騙或者叫SSL劫持,是一種典型的中間人攻擊,不過SSL劫持并非只是用于攻擊目的,在一些特殊情況下利用SSL劫持可以更順暢的訪問網(wǎng)絡(luò)。SSL劫持需要將攻擊者接入到瀏覽器與目標(biāo)網(wǎng)站之間,在傳輸數(shù)據(jù)的過程中,替換目標(biāo)網(wǎng)站發(fā)給瀏覽器的證書,之后解密傳輸?shù)臄?shù)據(jù),中間人攻擊最好的環(huán)境是在局域網(wǎng)中,因?yàn)榫钟蚓W(wǎng)中所有的計算機(jī)需要通過網(wǎng)關(guān)來接入互聯(lián)網(wǎng),因此攻擊者只需要實(shí)施一次中間人攻擊就可以順利的截獲所有計算機(jī)與網(wǎng)關(guān)之間傳輸?shù)臄?shù)據(jù)。一般SSL劫持,瀏覽器會給出證書錯誤的提示,如果繼續(xù)訪問,所有加密的數(shù)據(jù)都可以被攻擊者解密。
SSLStrip攻擊也需要將攻擊者設(shè)置為中間人,之后將HTTPS訪問替換為HTTP返回給瀏覽器,由于HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,從而截獲用戶訪問的數(shù)據(jù)。對于登錄賬號密碼等關(guān)鍵信息,可以在發(fā)送之前用javaScript進(jìn)行一次加密處理,這種方法對SSLScrip和SSL劫持都是有效的。
HTTPS也存在一些問題,那就是處理速度會變慢,一是由于存在HTTPS握手環(huán)節(jié),導(dǎo)致通信變慢,二是由于存在傳輸信息加密處理,消耗CPU及內(nèi)存資源,這對于高并發(fā)的服務(wù)器而言,更是一種性能瓶頸,所以服務(wù)器只是對含有敏感信息的數(shù)據(jù)進(jìn)行加密。
WebSoket原理HTTP協(xié)議的通信都是瀏覽器發(fā)出一個請求,服務(wù)器接收請求后進(jìn)行處理并返回結(jié)果,瀏覽器再將接收到的信息進(jìn)行渲染,這種機(jī)制對于實(shí)時性要求高的應(yīng)用場景顯得捉襟見肘,傳統(tǒng)請求-響應(yīng)模式的web開發(fā)通常采用輪詢方案,就是瀏覽器以一定時間間隔頻繁的向服務(wù)器請求數(shù)據(jù),來保持客戶端數(shù)據(jù)的實(shí)時更新,但是服務(wù)器數(shù)據(jù)可能并沒有更新,會帶來很多無謂的請求,浪費(fèi)帶寬,效率低下。
webSocket是HTML5下的一種新的協(xié)議,基于TCP傳輸協(xié)議,本身屬于應(yīng)用層協(xié)議,并且復(fù)用了HTTP握手通道。它實(shí)現(xiàn)了瀏覽器與服務(wù)器的全雙工通信,能更好的節(jié)省服務(wù)器資源和帶寬并達(dá)到實(shí)時通訊的目的,webSocket與HTTP長連接的區(qū)別:HTTP長連接在建立TCP連接后,在每個請求中任需要多帶帶發(fā)送請求頭,數(shù)據(jù)傳輸?shù)男实?,并且服?wù)器不能主動給瀏覽器推送數(shù)據(jù)。
WebSocket建立連接webSocket借用HTTP的協(xié)議來完成握手,首先通過HTTP發(fā)起請求報文,報文如下:
GET / HTTP/1,1 Host: localhost:8080 Origin: http://127.0.0.1:3000 Connection: Upgrade Upgrade: websocket Sec-WebSocket-key:w4v7O6xFTi36lq3RNcgctw== Sec-WebSocket-Protocol:chat, superchat Sec-WebSocket-Version:13
在上面的HTTP請求頭中,Connection和Upgrade字段表示請求服務(wù)器升級協(xié)議為webSocket,其中Sec-WebSocket-key的值是隨機(jī)生成的Base64編碼的字符串,Sec-WebSocket-Protocol和Sec-WebSocket-Version字段指定子協(xié)議和版本。服務(wù)器響應(yīng)頭如下:
HTTP/1.1 101 Switching Protocols Connection:Upgrade Upgrade: websocket Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=
狀態(tài)碼101表示協(xié)議切換,到此完成協(xié)議升級,后續(xù)的數(shù)據(jù)交互都按照新的協(xié)議來。Sec-WebSocket-Accept是根據(jù)請求字段Sec-WebSocket-key計算出來的,其計算過程為:
將Sec-WebSocket-Key跟258EAFA5-E914-47DA-95CA-C5AB0DC85B11字符串進(jìn)行拼接,形成新的字符串w4v7O6xFTi36lq3RNcgctw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11;
通過sha1算法計算出結(jié)果,并轉(zhuǎn)換成base64字符串。
瀏覽器會校驗(yàn)Sec-WebSocket-Accept的值,如果成功,webSocket的握手成功將開始接下來的數(shù)據(jù)傳輸。
webSocket傳輸數(shù)據(jù)的基本單位是幀,一般webScoket傳輸?shù)囊粭l消息會被切割成多個幀,數(shù)據(jù)幀有一個標(biāo)志位FIN,F(xiàn)IN=1表示這是消息的最后一幀,接收端接收到幀數(shù)據(jù)后,如果該幀的FIN標(biāo)識為1,就會將已經(jīng)接收到的數(shù)據(jù)幀組裝成一個完整的消息。
WebSocket實(shí)戰(zhàn) HTML5中的WebSoketvar Socket = new WebSocket(url,[protocol])
URL字符串必須以“ws”或“wss”(加密通信時)文字作為開頭,protocol是Web應(yīng)用能夠使用的協(xié)議,可以是字符串,也可以是數(shù)組,如果一下代碼中proto1和proto2是定義明確、可能已注冊且標(biāo)準(zhǔn)化的協(xié)議名稱,它們能夠同時為客戶端和服務(wù)器所理解,服務(wù)器會從列表中選擇首選協(xié)議。webSocket支持onopen、onmessage、onclose、onerror四個異步事件。
if(window.WebScoket){ var url = "ws://localhost:8080/test" var socket = new WebSocket(url,["proto1","proto2"]) socket.onopen = function(){ socket.send("message") } socket.onmessage = function(e){ console.log(e.data) } socket.onclose = function(){ } socket.onerror = function(){ } var arr = new Uint8Array([8,3,4,5,7,0,9]) socket.send(arr.buffer) socket.binaryType = "arrayBuffer" // 設(shè)置接收ArrayBuffer對象 socket.binaryType = "blob" // 設(shè)置接收blob對象 socket.onmessage = function(e){ console.log(e.data) } }
webSocket.bufferAmount屬性表示已在WebSocket上發(fā)送但尚未寫入網(wǎng)絡(luò)的字節(jié)數(shù),一般用于調(diào)節(jié)發(fā)送速率。WebSocket API支持以二進(jìn)制發(fā)送Blob和ArrayBuffer實(shí)例。當(dāng)然也可以設(shè)置接收Blob和ArrayBuffer對象。
Nodejs中的webSocketwebSocket的數(shù)據(jù)幀格式為以下部分:
FIN:1位,表示是否結(jié)束, 1:結(jié)束
RSV[1-3]:用于協(xié)商擴(kuò)展
opcode: 4位,0,1,2屬于數(shù)據(jù)幀,8,9,10屬于控制幀
mask:掩碼,0表示不使用亞掩碼,一般服務(wù)器回消息不會使用掩碼,接收消息需要掩碼
payloadLen 0-125 直接表示 數(shù)據(jù)長度
126,后面16位對應(yīng)數(shù)據(jù)長度 127,后面64位對應(yīng)數(shù)據(jù)長度
masking-key:如果mask為1,后面32位作為masking-key,mask為0,則缺省
payload Data: 負(fù)載的數(shù)據(jù)
其連接的代碼為:
const server = http.createServer((req,res) => { res.writeHead(200,{"Content-Type":"text/plain"}) res.send("hello world") }) server.on("upgrade",(req,socket,upgradeHead) => { var key = req.headers["sec-websocket-key"] var accept = crypto.createHash("sha1").update(key + GUID).digest("base64") var headers = [ "HTTP/1.1 101 Switching protocols", "Upgrade: websocket", "Connection: Upgrade", "Sec-WebSocket-Accept: " + accept, " " ] socket.setNoDelay(true) socket.write(headers.join(" ")) var websocket = new WebSocket() websocket.setSocket(socket) }) // websocket對象 function WebSocket(){ this.socket = null this.buffer = null } WebSocket.prototype.setSocket = function(socket){ this.socket = socket var data = [] this.socket.on("data",(chunk) => { data.push(chunk) }) this.socket.on("end",() => { this.buffer = Buffer.concat(data) var frame = this.decodeMessage(this.buffer) console.log(frame) console.log(frame.payloadData.toString()) }) } WebSocket.prototype.decodeMessage = (buffer) => { let start = 0 let frame = { isFinal:(buffer[start] & 0x80) === 0x80, opcode:buffer[start++] & 0xF, masked:(buffer[start] & 0x80) === 0x80, payloadLen:buffer[start++] & 0x7F, maskingKey:"", payloadData:null } if(frame.payloadLen === 126){ frame.payloadLen = (buffer[start++] << 8) + buffer[start++] }else if(frame.payloadLen === 127){ frame.payloadLen = 0 for(let i = 7; i >= 0; i--){ frame.payloadLen = (buffer[start++] << (8 * i)) } } if(frame.payloadLen){ if(frame.masked){ const maskingKey = [ buffer[start++], buffer[start++], buffer[start++], buffer[start++] ] frame.maskingKey = maskingKey frame.payloadData = buffer.slice(start,start + frame.payloadLen) .map((byte,idx) => byte ^ maskingKey[idx % 4]) }else{ frame.payloadData = buffer.slice(start,start + frame.payloadLen) } } return frame } module.exports = WebSocket
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/61935.html
摘要:面試網(wǎng)絡(luò)了解及網(wǎng)絡(luò)基礎(chǔ)對端傳輸詳解與攻防實(shí)戰(zhàn)本文從屬于筆者的信息安全實(shí)戰(zhàn)中滲透測試實(shí)戰(zhàn)系列文章。建議先閱讀下的網(wǎng)絡(luò)安全基礎(chǔ)。然而,該攻擊方式并不為大家所熟知,很多網(wǎng)站都有的安全漏洞。 面試 -- 網(wǎng)絡(luò) HTTP 現(xiàn)在面試門檻越來越高,很多開發(fā)者對于網(wǎng)絡(luò)知識這塊了解的不是很多,遇到這些面試題會手足無措。本篇文章知識主要集中在 HTTP 這塊。文中知識來自 《圖解 HTTP》與維基百科,若...
摘要:下面我們從前端基礎(chǔ)和底層原理開始講起。對于和這三個對應(yīng)于矢量圖位圖和圖的渲染來說,給前端開發(fā)帶來了重武器,很多小游戲也因此蓬勃發(fā)展。這篇文章受眾之大,后來被人重新整理并發(fā)布為,其中還包括中文版。 showImg(https://segmentfault.com/img/bVbjM5r?w=1142&h=640); 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 這...
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們在學(xué)習(xí)的過程中,由于對一些概念理解得不是很清楚,但是又想要通過一些方式把它記下來,于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡要總結(jié)。 多線程開發(fā)有兩個核心問題,一個是競爭,另一個是協(xié)作。競爭會出現(xiàn)線程安全問題,所以,本...
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們在學(xué)習(xí)的過程中,由于對一些概念理解得不是很清楚,但是又想要通過一些方式把它記下來,于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡要總結(jié)。 多線程開發(fā)有兩個核心問題,一個是競爭,另一個是協(xié)作。競爭會出現(xiàn)線程安全問題,所以,本...
閱讀 834·2023-04-25 20:47
閱讀 2602·2019-08-30 15:53
閱讀 1019·2019-08-26 14:05
閱讀 955·2019-08-26 11:59
閱讀 1760·2019-08-26 11:43
閱讀 1785·2019-08-26 10:57
閱讀 1421·2019-08-23 18:23
閱讀 2805·2019-08-23 12:57