成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【HTTP基礎(chǔ)】HTTPS原理及WebSocket原理

fyber / 1453人閱讀

摘要:使用約定好的計(jì)算握手消息,并使用生產(chǎn)的隨機(jī)數(shù)對(duì)消息進(jìn)行加密,最后將之前生成的所有消息發(fā)送給網(wǎng)站。之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對(duì)稱加密算法進(jìn)行加密。支持四個(gè)異步事件。

由于HTTP沒(méi)有加密機(jī)制,其傳輸?shù)膬?nèi)容很容易泄漏,并且HTTP協(xié)議沒(méi)法確認(rèn)通信方,也無(wú)法保證接收到的報(bào)文在傳輸過(guò)程中是否被篡改,因此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é)議通信。

加密方法

近代的加密方法中加密算法是公開(kāi)的,而密鑰卻是保密的,加密和解密都需要用到密鑰,沒(méi)有密鑰就沒(méi)法對(duì)加密內(nèi)容進(jìn)行解密,通過(guò)這種方式得以保持加密方法的安全性。加密和解密同用一個(gè)密鑰的方式陳為共享密鑰加密,也被稱為對(duì)稱密鑰加密。以共享密鑰方式的加密必須將密鑰也發(fā)給對(duì)方,在網(wǎng)絡(luò)上發(fā)送密鑰很容易被攻擊者獲取。并且服務(wù)器如果對(duì)所有客戶端都使用同樣的共享密鑰,無(wú)異于沒(méi)有加密,所以HTTPS采用生成的隨機(jī)數(shù)來(lái)作為共享加密算法的密鑰。

公開(kāi)密鑰加密使用一對(duì)非對(duì)稱的密鑰,一把叫做私有密鑰,一把叫做公有密鑰,發(fā)送密文的一方使用對(duì)方的公開(kāi)密鑰進(jìn)行加密處理,對(duì)方收到被加密的信息后,再使用自己的私有密鑰進(jìn)行解密,這樣就不用擔(dān)心密鑰被攻擊者獲取。

HTTPS采用共享密鑰加密和公開(kāi)密鑰加密兩者并用的混合加密機(jī)制,如果僅僅保證密鑰的安全性,使用公開(kāi)密鑰加密的方式就可以實(shí)現(xiàn)了,但是公開(kāi)密鑰加密方式比共享密鑰加密,其處理速度要慢。所以HTTPS在交換密鑰環(huán)節(jié)采用公開(kāi)密鑰加密方式,之后建立通信交換報(bào)文階段采用共享密鑰加密方式。

公開(kāi)密鑰加密方式也不能保證公開(kāi)密鑰本身的真實(shí)性,比如,在與某臺(tái)服務(wù)器建立連接時(shí),無(wú)法保證接收到的公開(kāi)密鑰就是需要連接的那個(gè)服務(wù)器的密鑰,這個(gè)時(shí)候可以采用數(shù)字證書(shū)認(rèn)證機(jī)構(gòu)和其相關(guān)機(jī)關(guān)頒發(fā)的公開(kāi)密鑰證書(shū)。

HTTPS的握手過(guò)程

首先,客戶端會(huì)發(fā)送一個(gè)https的請(qǐng)求,把自身支持的一系列密鑰算法組件(Cipher Suite)發(fā)送給服務(wù)器。

服務(wù)器接收到客戶端所有的Cipher后與自身支持的對(duì)比,如果不支持則連接斷開(kāi),反之則會(huì)從中選擇一種加密算法和HASH算法以證書(shū)的形式返回給客戶端,證書(shū)中包含了加密公鑰,頒證機(jī)構(gòu),網(wǎng)站地址,失效日期等等。

客戶端收到服務(wù)器端的響應(yīng)后會(huì)做以下幾件事:
1:驗(yàn)證證書(shū)的合法性,頒發(fā)證書(shū)的機(jī)構(gòu)是否合法與是否過(guò)期,證書(shū)中包含的網(wǎng)站地址是否與正在訪問(wèn)的地址一致等,證書(shū)驗(yàn)證通過(guò)后,在瀏覽器的地址欄會(huì)加上一把小鎖。
2:證書(shū)驗(yàn)證通過(guò)后,生成隨機(jī)密碼,用證書(shū)中的公鑰加密。
3:使用約定好的HASH計(jì)算握手消息,并使用生產(chǎn)的隨機(jī)數(shù)對(duì)消息進(jìn)行加密,最后將之前生成的所有消息發(fā)送給網(wǎng)站。

服務(wù)器接收到客戶端傳來(lái)的密文,用自己的私鑰來(lái)解密取出隨機(jī)數(shù)密碼,然后用隨機(jī)數(shù)密碼解密瀏覽器發(fā)送過(guò)來(lái)的握手消息,并驗(yàn)證HASH是否是與瀏覽器發(fā)來(lái)的一致,然后使用密碼加密一段握手消息,發(fā)送給瀏覽器。

客戶端用隨機(jī)數(shù)解密并計(jì)算出握手消息的HASH,如果與服務(wù)器端發(fā)來(lái)的HASH一致,此時(shí)握手過(guò)程結(jié)束。

之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對(duì)稱加密算法進(jìn)行加密。因?yàn)檫@串密碼只有客戶端和服務(wù)器知道,所有即使中間請(qǐng)求被攔截也是沒(méi)法解密數(shù)據(jù)的,以此保證了通信的安全。
其中非對(duì)稱加密算法用于在握手消息過(guò)程中加密生成的隨機(jī)數(shù)密碼,對(duì)稱加密算法用于對(duì)真正傳輸?shù)臄?shù)據(jù)進(jìn)行加密,而HASH算法用于驗(yàn)證數(shù)據(jù)的完整性,TLS握手過(guò)程中如果有任何錯(cuò)誤,都會(huì)使加密連接斷開(kāi),從而阻止了隱私信息的傳輸,由于HTTPS非常的安全,攻擊者無(wú)法從中找到下手的地方,于是更多的是采用了假證書(shū)的手法來(lái)欺騙客戶端,從而獲取明文的信息。

HTTPS攻擊手段

瀏覽器在對(duì)證書(shū)進(jìn)行驗(yàn)證時(shí),以下幾種情況會(huì)導(dǎo)致驗(yàn)證失?。?/p>

SSL證書(shū)不是由受信任的CA機(jī)構(gòu)頒發(fā)的

證書(shū)過(guò)期

訪問(wèn)的網(wǎng)站域名與證書(shū)綁定的域名不一致

對(duì)HTTPS最常見(jiàn)的攻擊手段就是SSL證書(shū)欺騙或者叫SSL劫持,是一種典型的中間人攻擊,不過(guò)SSL劫持并非只是用于攻擊目的,在一些特殊情況下利用SSL劫持可以更順暢的訪問(wèn)網(wǎng)絡(luò)。SSL劫持需要將攻擊者接入到瀏覽器與目標(biāo)網(wǎng)站之間,在傳輸數(shù)據(jù)的過(guò)程中,替換目標(biāo)網(wǎng)站發(fā)給瀏覽器的證書(shū),之后解密傳輸?shù)臄?shù)據(jù),中間人攻擊最好的環(huán)境是在局域網(wǎng)中,因?yàn)榫钟蚓W(wǎng)中所有的計(jì)算機(jī)需要通過(guò)網(wǎng)關(guān)來(lái)接入互聯(lián)網(wǎng),因此攻擊者只需要實(shí)施一次中間人攻擊就可以順利的截獲所有計(jì)算機(jī)與網(wǎng)關(guān)之間傳輸?shù)臄?shù)據(jù)。一般SSL劫持,瀏覽器會(huì)給出證書(shū)錯(cuò)誤的提示,如果繼續(xù)訪問(wèn),所有加密的數(shù)據(jù)都可以被攻擊者解密。

SSLStrip攻擊也需要將攻擊者設(shè)置為中間人,之后將HTTPS訪問(wèn)替換為HTTP返回給瀏覽器,由于HTTP協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,從而截獲用戶訪問(wèn)的數(shù)據(jù)。對(duì)于登錄賬號(hào)密碼等關(guān)鍵信息,可以在發(fā)送之前用javaScript進(jìn)行一次加密處理,這種方法對(duì)SSLScrip和SSL劫持都是有效的。

HTTPS也存在一些問(wèn)題,那就是處理速度會(huì)變慢,一是由于存在HTTPS握手環(huán)節(jié),導(dǎo)致通信變慢,二是由于存在傳輸信息加密處理,消耗CPU及內(nèi)存資源,這對(duì)于高并發(fā)的服務(wù)器而言,更是一種性能瓶頸,所以服務(wù)器只是對(duì)含有敏感信息的數(shù)據(jù)進(jìn)行加密。

WebSoket原理

HTTP協(xié)議的通信都是瀏覽器發(fā)出一個(gè)請(qǐng)求,服務(wù)器接收請(qǐng)求后進(jìn)行處理并返回結(jié)果,瀏覽器再將接收到的信息進(jìn)行渲染,這種機(jī)制對(duì)于實(shí)時(shí)性要求高的應(yīng)用場(chǎng)景顯得捉襟見(jiàn)肘,傳統(tǒng)請(qǐng)求-響應(yīng)模式的web開(kāi)發(fā)通常采用輪詢方案,就是瀏覽器以一定時(shí)間間隔頻繁的向服務(wù)器請(qǐng)求數(shù)據(jù),來(lái)保持客戶端數(shù)據(jù)的實(shí)時(shí)更新,但是服務(wù)器數(shù)據(jù)可能并沒(méi)有更新,會(huì)帶來(lái)很多無(wú)謂的請(qǐng)求,浪費(fèi)帶寬,效率低下。

webSocket是HTML5下的一種新的協(xié)議,基于TCP傳輸協(xié)議,本身屬于應(yīng)用層協(xié)議,并且復(fù)用了HTTP握手通道。它實(shí)現(xiàn)了瀏覽器與服務(wù)器的全雙工通信,能更好的節(jié)省服務(wù)器資源和帶寬并達(dá)到實(shí)時(shí)通訊的目的,webSocket與HTTP長(zhǎng)連接的區(qū)別:HTTP長(zhǎng)連接在建立TCP連接后,在每個(gè)請(qǐng)求中任需要多帶帶發(fā)送請(qǐng)求頭,數(shù)據(jù)傳輸?shù)男实?,并且服?wù)器不能主動(dòng)給瀏覽器推送數(shù)據(jù)。

WebSocket建立連接

webSocket借用HTTP的協(xié)議來(lái)完成握手,首先通過(guò)HTTP發(fā)起請(qǐng)求報(bào)文,報(bào)文如下:

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請(qǐng)求頭中,Connection和Upgrade字段表示請(qǐng)求服務(wù)器升級(jí)協(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é)議升級(jí),后續(xù)的數(shù)據(jù)交互都按照新的協(xié)議來(lái)。Sec-WebSocket-Accept是根據(jù)請(qǐng)求字段Sec-WebSocket-key計(jì)算出來(lái)的,其計(jì)算過(guò)程為:

將Sec-WebSocket-Key跟258EAFA5-E914-47DA-95CA-C5AB0DC85B11字符串進(jìn)行拼接,形成新的字符串w4v7O6xFTi36lq3RNcgctw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11;

通過(guò)sha1算法計(jì)算出結(jié)果,并轉(zhuǎn)換成base64字符串。

瀏覽器會(huì)校驗(yàn)Sec-WebSocket-Accept的值,如果成功,webSocket的握手成功將開(kāi)始接下來(lái)的數(shù)據(jù)傳輸。

webSocket傳輸數(shù)據(jù)的基本單位是幀,一般webScoket傳輸?shù)囊粭l消息會(huì)被切割成多個(gè)幀,數(shù)據(jù)幀有一個(gè)標(biāo)志位FIN,F(xiàn)IN=1表示這是消息的最后一幀,接收端接收到幀數(shù)據(jù)后,如果該幀的FIN標(biāo)識(shí)為1,就會(huì)將已經(jīng)接收到的數(shù)據(jù)幀組裝成一個(gè)完整的消息。

WebSocket實(shí)戰(zhàn) HTML5中的WebSoket
var Socket = new WebSocket(url,[protocol])

URL字符串必須以“ws”或“wss”(加密通信時(shí))文字作為開(kāi)頭,protocol是Web應(yīng)用能夠使用的協(xié)議,可以是字符串,也可以是數(shù)組,如果一下代碼中proto1和proto2是定義明確、可能已注冊(cè)且標(biāo)準(zhǔn)化的協(xié)議名稱,它們能夠同時(shí)為客戶端和服務(wù)器所理解,服務(wù)器會(huì)從列表中選擇首選協(xié)議。webSocket支持onopen、onmessage、onclose、onerror四個(gè)異步事件。

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對(duì)象
        socket.binaryType = "blob"       // 設(shè)置接收blob對(duì)象
        socket.onmessage = function(e){
            console.log(e.data)
        }
    }

webSocket.bufferAmount屬性表示已在WebSocket上發(fā)送但尚未寫(xiě)入網(wǎng)絡(luò)的字節(jié)數(shù),一般用于調(diào)節(jié)發(fā)送速率。WebSocket API支持以二進(jìn)制發(fā)送Blob和ArrayBuffer實(shí)例。當(dāng)然也可以設(shè)置接收Blob和ArrayBuffer對(duì)象。

Nodejs中的webSocket

webSocket的數(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ù)器回消息不會(huì)使用掩碼,接收消息需要掩碼
payloadLen 0-125 直接表示 數(shù)據(jù)長(zhǎng)度

        126,后面16位對(duì)應(yīng)數(shù)據(jù)長(zhǎng)度
        127,后面64位對(duì)應(yīng)數(shù)據(jù)長(zhǎng)度

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對(duì)象

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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61935.html

相關(guān)文章

  • 網(wǎng)絡(luò)與安全

    摘要:面試網(wǎng)絡(luò)了解及網(wǎng)絡(luò)基礎(chǔ)對(duì)端傳輸詳解與攻防實(shí)戰(zhàn)本文從屬于筆者的信息安全實(shí)戰(zhàn)中滲透測(cè)試實(shí)戰(zhàn)系列文章。建議先閱讀下的網(wǎng)絡(luò)安全基礎(chǔ)。然而,該攻擊方式并不為大家所熟知,很多網(wǎng)站都有的安全漏洞。 面試 -- 網(wǎng)絡(luò) HTTP 現(xiàn)在面試門檻越來(lái)越高,很多開(kāi)發(fā)者對(duì)于網(wǎng)絡(luò)知識(shí)這塊了解的不是很多,遇到這些面試題會(huì)手足無(wú)措。本篇文章知識(shí)主要集中在 HTTP 這塊。文中知識(shí)來(lái)自 《圖解 HTTP》與維基百科,若...

    Integ 評(píng)論0 收藏0
  • 程序員練級(jí)攻略(2018):前端基礎(chǔ)和底層原理

    摘要:下面我們從前端基礎(chǔ)和底層原理開(kāi)始講起。對(duì)于和這三個(gè)對(duì)應(yīng)于矢量圖位圖和圖的渲染來(lái)說(shuō),給前端開(kāi)發(fā)帶來(lái)了重武器,很多小游戲也因此蓬勃發(fā)展。這篇文章受眾之大,后來(lái)被人重新整理并發(fā)布為,其中還包括中文版。 showImg(https://segmentfault.com/img/bVbjM5r?w=1142&h=640); 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 這...

    widuu 評(píng)論0 收藏0
  • 原理解釋 - 收藏集 - 掘金

    摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開(kāi)發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...

    AlphaGooo 評(píng)論0 收藏0
  • 原理解釋 - 收藏集 - 掘金

    摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開(kāi)發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...

    forrest23 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<