一道面試題囊括多個高頻知識點的確實不多,但確實有一個神奇的藥引子——瀏覽器安全能串聯起12個前端硬核知識點,一起來瞅瞅!!!
一、概述
1.1 Web頁面安全
說到Web頁面安全你會想到哪些問題呢?
- 什麼是同源、什麼是同源策略、同源策略的表現是什麼?
- 瀏覽器出讓了同源策略的哪些安全性?
- 跨域解決方案有哪些?
- JSONP如何實現?
- CORS你瞭解哪些?
針對Web頁面安全有哪些常見的攻擊手段(XSS、CSRF)?
1.2 瀏覽器網路安全
說到瀏覽器網路安全你會想到哪些問題呢?
- 什麼是請求報文?
- 什麼是響應報文?
- HTTP缺點
- HTTPS基礎知識點
HTTPS流程
1.3 瀏覽器系統安全
說到瀏覽器系統安全你會想到哪些問題呢?
- 安全沙箱
二、Web頁面安全
2.1 同源策略
2.1.1 同源
跨域本質其實就是指兩個地址不同源,不同源的反面不就是同源,同源指的是:如果兩個URL的協議、域名和埠號都相同,則就是兩個同源的URL。
// 非同源:協議不同
http://www.baidu.com
https://www.baidu.com
// 同源:協議、域名、埠號都相同
http://www.baidu.com
http://www.baidu.com?query=1
2.1.2 同源策略
同源策略是一個重要的安全策略,它用於限制一個origin的文件或者它載入的載入的指令碼如何能與另一個源的資源進行互動。其主要是為了保護使用者資訊的安全,防止惡意的網站竊取資料,是瀏覽器在Web頁面層面做的安全保護。
2.1.3 同源策略的表現
既然同源策略是瀏覽器在Web頁面層面做的保護,那麼該層面哪些位置需要進行保護呢?總結下來主要包含三個層面:DOM層面、資料層面、網路層面。
- DOM層面
同源策略限制了來自不同源的JavaScript指令碼對當前DOM物件讀和寫的操作。
- 資料層面
同源策略限制了不同源的站點讀取當前站點的Cookie、IndexedDB、localStorage等資料。
- 網路層面
同源策略限制了通過XMHttpRequest等方式將站點的資料傳送給不同源的站點。
2.1.4 瀏覽器出讓了同源策略的哪些安全性?
2.2 跨域分類
同源策略保證了瀏覽器的安全,但是如果將這三個層面限制的死死的,則會讓程式設計師的開發工作舉步維艱,所以瀏覽器需要在最嚴格的同源策略限制下做一些讓步,這些讓步更多了是在安全性與便捷性的權衡。其實跨域的方式就可以認為是瀏覽器出讓了一些安全性或在遵守瀏覽器同源策略前提下所採取的一種折中手段。
2.2.1 DOM層面和資料層面分類
根據同源策略,如果兩個頁面不同源,無法互相操作DOM、訪問資料,但是兩個不同源頁面之間進行通訊是比較常見的情形,典型的例子就是iframe視窗與父視窗之間的通訊。隨著歷史的車輪,實現DOM層面間通訊的方式有多種,如下所示:
- 片段識別符號
片段識別符號其核心原理就是通過監聽url中hash的改變來實現資料的傳遞,想法真的很巧妙。
// 父頁面parentHtml.html
<!DOCTYPE html>
<html lang="zh">
<head>
<title></title>
</head>
<body>
我是父頁面
<button id='btn'>父傳給子</button>
<iframe src="./childHtml.html" id="childHtmlId"></iframe>
</body>
<script>
window.onhashchange = function() {
console.log(decodeURIComponent(window.location.hash));
};
document.getElementById('btn').addEventListener('click', () => {
const iframeDom = document.getElementById('childHtmlId');
iframeDom.src += '#父傳給子';
});
</script>
</html>
// 子頁面childHtml.html
<!DOCTYPE html>
<html lang="zh">
<head>
<title></title>
</head>
<body>
我是子頁面
<button id='btn'>子傳給父</button>
</body>
<script>
window.onhashchange = function() {
console.log(decodeURIComponent(window.location.hash));
};
document.getElementById('btn').addEventListener('click', () => {
parent.location.href += '#子傳給父';
});
</script>
</html>
- window.name
瀏覽器視窗有window.name屬性,這個屬性的最大特點是,無論是否同源,只要在同一個視窗裡,前一個網頁設定了這個屬性,後一個網頁可以讀取它。如果需要實現父頁面和跨域的子頁面之間的通訊,需要一個和父頁面同源的子頁面作為中介,將跨域的子頁面中的資訊傳遞過來。(好麻煩呀,強烈不推薦使用,此處就不寫對應的程式碼啦)
- document.domain
document.domain是存放文件的伺服器的主機名,可通過手動設定將其設定成當前域名或者上級的域名,當具有相同document.domain的頁面就相當於處於同域名的伺服器上,如果其域名和埠號相同就可以實現跨域訪問資料了。
- postMessage(強烈推薦)
window.postMessage是HTML5新增的跨文件通訊API,該API,允許跨視窗通訊,不論這兩個視窗是否同源。
// 父頁面
<!DOCTYPE html>
<html lang="zh">
<head>
<title></title>
</head>
<body>
我是父頁面
<button id='btn'>父傳給子</button>
<iframe src="http://127.0.0.1:5500/024/childHtml.html" id="childHtmlId"></iframe>
</body>
<script>
window.addEventListener('message', function(event) {
console.log('父頁面接收到資訊', event.data);
});
document.getElementById('btn').addEventListener('click', () => {
const iframeDom = document.getElementById('childHtmlId');
iframeDom.contentWindow.postMessage('我是執鳶者1', 'http://127.0.0.1:5500/024/childHtml1.html');
});
</script>
</html>
// 子頁面
<!DOCTYPE html>
<html lang="zh">
<head>
<title></title>
</head>
<body>
我是子頁面
<button id='btn'>子傳給父</button>
</body>
<script>
window.addEventListener('message', function(event) {
console.log('子頁面接收到資訊', event.data);
});
document.getElementById('btn').addEventListener('click', () => {
parent.postMessage('我是執鳶者2', 'http://127.0.0.1:5500/024/parentHtml1.html');
});
</script>
</html>
2.2.2 網路層面
根據同源策略,瀏覽器預設是不允許XMLHttpRequest物件訪問非同一站點的資源的,這會大大制約生產力,所以需要破解這種限制,實現跨域訪問資源。目前廣泛採用的主要有三種方式(注:該出不給出具體程式碼,後續會有專門的百題斬進行詳細闡述):
2.2.2.1 通過代理實現
同源策略是瀏覽器為了安全制定的策略,所以服務端不會存在這樣的限制,這樣我們就可以將請求打到同源的伺服器上,然後經由同源伺服器代理至最終需要的伺服器,從而實現跨域請求的目的。例如可以通過Nginx、Node中介軟體等。
2.2.2.2 JSONP的方式
JSONP是一種藉助script元素實現跨域的技術,它並沒有使用XMLHttpRequest物件,其能夠實現跨域主要得益於script有兩個特點:
(1)src屬效能夠訪問任何URL資源,並不會受到同源策略的限制;
(2)如果訪問的資源包含JavaScript程式碼,其會在下載後自動執行。
下面一起來實現一下JSONP
- 全域性掛載一個接收資料的函式;
- 建立一個script標籤,並在其標籤的onload和onerror事件上掛載對應處理函式;
- 將script標籤掛載到頁面中,向服務端發起請求;
- 服務端接收傳遞過來的引數,然後將回撥函式和資料以呼叫的形式輸出;
- 當script元素接收到影響中的指令碼程式碼後,就會自動執行它們。
function createScript(url, charset) {
const script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
charset && script.setAttribute('charset', charset);
script.setAttribute('src', url);
script.async = true;
return script;
}
function jsonp(url, onsuccess, onerror, charset) {
const hash = Math.random().toString().slice(2);
window['jsonp' + hash] = function (data) {
if (onsuccess && typeof(onsuccess) === 'function') {
onsuccess(data);
}
}
const script = createScript(url + '?callback=jsonp' + hash, charset);
// 監聽載入成功的事件,獲取資料,這個位置用了兩個事件onload和onreadystatechange是為了相容IE,因為IE9之前不支援onload事件,只支援onreadystatechange事件
script.onload = script.onreadystatechange = function() {
//若不存在readyState事件則證明不是IE瀏覽器,可以直接執行,若是的話,必須等到狀態變為loaded或complete才可以執行
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
script.onload = script.onreadystatechange = null;
// 移除該script的DOM物件
if (script.parentNode) {
script.parentNode.removeChild(script);
}
// 刪除函式或變數
window['jsonp' + hash] = null;
}
};
script.onerror = function() {
if (onerror && typeof(onerror) === 'function') {
onerror();
}
}
// 新增標籤,傳送請求
document.getElementsByTagName('head')[0].appendChild(script);
}
2.2.2.3 CORS方式
跨域資源共享(CORS),該機制可以進行跨域訪問控制,從而使跨域資料傳輸得以安全進行。(實現一個跨域請求的方式,其中html訪問網址為http://127.0.0.1:8009; 伺服器監聽埠為:8010)
一、整體流程CORS的通訊流程是瀏覽器自動完成,不需要使用者參與,其核心點是伺服器,只要伺服器實現了CORS介面就可以實現跨源通訊了。雖然是瀏覽器自動完成,但是瀏覽器其實還是根據請求時欄位的不同分為簡單請求和非簡單請求的,下面對這兩者進行簡要介紹。
- 簡單請求
(1) 定義
只要滿足以下兩個條件就屬於簡單請求:
1) 請求方法是一下三種方法之一:HEAD、GET、POST;
2) HTTP的頭資訊不超出以下幾種欄位:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(其值為application/x-www-form-urlencoded、multipart/form-data、text/plain三個中的一個)。
(2)流程
簡單請求的整個流程可以歸結為以下步驟:
1) 瀏覽器直接發出CORS請求,具體來說就是在頭資訊之中增加一個Origin欄位,該欄位用來說明請求來自哪個源(協議+域名+埠),伺服器根據這個值決定是否同意這次請求;
2)當伺服器接收到請求後,根據Origin判定指定的源是否在許可的範圍內。
3)如果不在許可範圍內,伺服器會返回一個正常的HTTP回應,瀏覽器發現該回應的頭資訊沒有包含Access-Control-Allow-Origin欄位,就知道出錯了,從而丟擲錯誤,被XML的onerror回撥函式捕獲。(注意:由於正常回應,其狀態碼為200,所以該錯誤不能通過狀態碼識別)
4)如果Origin指定的域名在許可範圍內,伺服器返回的響應中會多出幾個頭資訊欄位(Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Expose-Header等)。
(3)關鍵欄位
1) Access-Control-Allow-Origin
必須欄位,該值要麼是請求的Origin欄位值,要麼是一個*(表示接受任意域名的請求)。
2)Access-Control-Allow-Credentials
可選欄位,其值是一個布林值,表示是否允許傳送Cookie。預設是不傳送Cookie值,當設定為true時,表示伺服器明確許可,Cookie可以包含在請求中傳送給伺服器。(注意:傳送Cookie時要注意兩點:一方面在Ajax請求中需要設定withCredentials屬性;另一方面不能將Access-Control-Allow-Origin設定為*,需要指定明確的、與請求網頁一致的域名)
3)Access-Control-Expose-Header
可選欄位,當CORS請求時,XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位(Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma),如果想獲取其它欄位必須在Access-Control-Expose-Header中指定。
- 非簡單請求
(1)定義
不是簡單請求的就是非簡單請求,非簡單請求是那種對伺服器有特殊要求的請求,比如請求方法是PUT或Delete,或者Content-Type欄位的型別是application/json.
(2)流程
非簡單請求相比於簡單請求較複雜,在發起正式請求之前會進行一次預檢請求,通過預檢請求的結果來決定是否進行後續的正式通訊。
1)瀏覽器發起預檢請求,該請求的請求方法是options,該請求是用來詢問的;
2)伺服器收到“預檢”請求以後,檢查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers欄位以後,確認允許跨源請求,就可以做出回應。
3)如果瀏覽器否定了“預檢”請求,會返回一個正常的HTTP回應,但是沒有任何CORS相關的頭資訊欄位,這時瀏覽器就會認定伺服器不同意預檢請求,觸發錯誤;
4)如果瀏覽器通過了“預檢”請求,以後每次瀏覽器正常的CORS請求就跟簡單請求一樣,會有一個Origin頭資訊欄位,伺服器的回應也會有一個Access-Control-Allow-Origin頭資訊欄位;
(3)關鍵欄位
1)Access-Control-Request-Method
必須欄位,用來列出瀏覽器的CORS請求會用到哪些HTTP方法。
2)Access-Control-Request-Headers
該欄位是一個逗號分隔的字串,用來指定瀏覽器CORS請求會額外傳送的頭資訊欄位。
3)Access-Control-Allow-Methods
必須欄位,該值是一個逗號分隔的字串,用來表明伺服器支援的所有跨域請求的方法。
4)Access-Control-Allow-Headers
該值是一個逗號分隔的字串,表明伺服器支援的所有頭資訊欄位。
5)Access-Control-Max-Age
用來請求預檢請求的有效期,單位為秒。
- 簡單實現
(1)html頁面內容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test CORS</title>
</head>
<body>
CORS
<script src="https://code.bdstatic.com/npm/axios@0.20.0/dist/axios.min.js"></script>
<script>
axios('http://127.0.0.1:8010', {
method: 'get'
}).then(console.log)
</script>
</body>
</html>
(2)伺服器端程式碼
const express = require('express');
const app = express();
app.get('/', (req, res) => {
console.log('get請求收到了!!!');
res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:8009');
res.send('get請求已經被處理');
})
app.listen(8010, () => {
console.log('8010 is listening')
});
2.3 兩種攻擊方式
2.3.1 XSS
2.3.1.1 定義
跨站指令碼攻擊(XSS;Cross Site Scripting) 是指黑客往 HTML 檔案中或者 DOM 中注入惡意指令碼,從而在使用者瀏覽頁面時利用注入的惡意指令碼對使用者實施攻擊的一種手段。
2.3.1.2 產生的影響
XSS攻擊產生的影響主要有:盜取Cookie資訊、監聽使用者行為、修改DOM、在頁面內生成浮窗廣告等。
2.3.1.3 注入方式
XSS注入方式有儲存型XSS攻擊、反射型XSS攻擊、基於DOM的XSS攻擊。
2.3.1.4 什麼情況容易發生XSS攻擊
容易發生XSS攻擊的位置主要有兩個:
- 資料從一個不可靠的連結進入到一個web應用程式
- 沒有過濾掉惡意程式碼的動態內容被髮送給Web使用者
2.3.1.5 如何阻止XSS攻擊
阻止XSS攻擊的方式主要有三種:
- 伺服器對輸入指令碼進行過濾或轉碼;
- 充分利用CSP;
- 使用HttpOnly屬性
2.3.2 CSRF
2.3.2.1 定義
跨站請求偽造(CSRF;Cross-site request forgery)指的是黑客引誘使用者開啟黑客的網站,在黑客的網站中,利用使用者的登入狀態發起的跨站請求
2.3.2.2 產生影響
產生影響主要有以下幾點:
2.3.2.3 攻擊原理
2.3.2.4 攻擊的前提條件
攻擊的前提條件主要有以下三點:
2.3.2.5 攻擊方式
實施CSRF攻擊的方式主要有以下三點:
- 自動發起Get請求;
- 自動發起POST請求;
- 引誘使用者點選連結
2.3.2.6 防止CSRF攻擊的策略
防止CSRF攻擊的策略主要有以下三種:
- 充分利用好Cookie的SameSite屬性;
- 在伺服器端驗證請求的來源站點;
- CSRF Token。
三、瀏覽器安全
3.1 請求報文
HTTP請求報文主要包括:請求行、請求頭部以及請求的資料(實體),下面一起看看其組成內容:
3.1.1 請求行
請求行包含:方法欄位、URI欄位和協議版本
方法欄位
GET(請求獲取內容);
POST(提交表單);
HEAD(請求資源響應訊息報頭);
PUT(傳輸檔案);
DELETE(請求刪除URI指向的資源);
OPTIONS(查詢針對請求URI指定的資源支援的方法);
TRACE(追蹤請求經過路徑);
CONNECT(要求用隧道協議連線代理)。
- URI欄位
協議版本
指的就是本次請求的HTTP協議版本,例如HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP/3.0.
3.1.2 請求頭部
常見標頭有:Connection標頭(連線管理)、Host標頭(指定請求資源的主機)、Range標頭(請求實體的位元組範圍)、User-Agent標頭(包含發出請求的使用者資訊)、Accept標頭(首選的媒體型別)、Accept-Language(首選的自然語言)
3.1.3 請求實體
HTTP請求的body主要用於提交表單場景。實際上,http請求的body是比較自由的,只要瀏覽器端傳送的body服務端認可就可以了。一些常見的body格式是:
- application/json
- application/x-www-form-urlencoded
- multipart/form-data
- text/xml
使用html的form標籤提交產生的html請求,預設會產生 application/x-www-form-urlencoded 的資料格式,當有檔案上傳時,則會使用multipart/form-data。
3.2 響應報文
HTTP響應報文分為三個部分:狀態行、首部行和響應體.
3.2.1 狀態行
狀態行是由版本、狀態碼和原因語句組成,下面來看看一些常用的狀態碼。
- 1xx:這一型別的狀態碼,代表請求已被接受,需要繼續處理。這類響應是臨時響應,只包含狀態行和某些可選的響應頭資訊,並以空行結束
- 2xx:這一型別的狀態碼,代表請求已成功被伺服器接收、理解並接受
200---OK/請求已經正常處理完畢;
204---請求處理成功,但沒有資源返回;
206---表示客戶端進行了範圍請求,而伺服器成功執行了這部分的GET請求;
- 3xx:這類狀態碼代表需要客戶端採取進一步的操作才能完成請求。通常,這些狀態碼用來重定向,後續的請求地址(重定向目標)在本次響應的Location域中指明
301---請求永久重定向 被請求的資源已永久移動到新位置,並且將來任何對此資源的引用都應該使用本響應返回的若干個 URI 之一。如果可能,擁有連結編輯功能的客戶端應當自動把請求的地址修改為從伺服器反饋回來的地址。
302---請求臨時重定向 由於這樣的重定向是臨時的,客戶端應當繼續向原有地址傳送以後的請求。只有在Cache-Control或Expires中進行了指定的情況下,這個響應才是可快取的。
303---表示由於請求對應的資源存在著另一個URI,應使用GET方法定向獲取請求的資源
304---表示客戶端傳送附帶條件的請求(指採用GET方法的請求報文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部)時,服務端允許請求訪問資源,但未滿足條件的情況
307---臨時重定向,與302含義相同,但是307會遵照瀏覽器標準,不會從POST變成GET
- 4xx:這類狀態碼代表客戶端類的錯誤
400---客戶端請求存在語法錯誤
401---當前請求需要使用者驗證。
403---伺服器已經理解請求,但是拒絕執行它。與401響應不同的是,身份驗證並不能提供任何幫助
404---請求失敗,請求所希望得到的資源未被在伺服器上發現。
405---請求行中指定的請求方法不能被用於請求相應的資源。
- 5xx:伺服器類的錯誤
500---伺服器遇到了一個未曾預料的狀況,導致了它無法完成對請求的處理。
501---伺服器不支援當前請求所需要的某個功能。當伺服器無法識別請求的方法,並且無法支援其對任何資源的請求。
503---由於臨時的伺服器維護或者過載,伺服器當前無法處理請求。
505---伺服器不支援,或者拒絕支援在請求中使用的 HTTP 版本。
3.2.2 響應首部
常見的響應首部有:Date(響應的時間)、Via(報文經過的中間節點)、Last-Modified(上一次修改時間)、Etag(與此實體相關的實體標記)、Connection(連線狀態)、Accept-Ranges(伺服器可接收的範圍型別)、Content-Type(資源型別)
3.2.3 響應體
響應體就是響應的訊息體,如果是純資料就是返回純資料,如果請求的是HTML頁面,那麼返回的就是HTML程式碼,如果是JS就是JS程式碼等。
3.2 HTTP的缺點
正是由於HTTP存在一系列的缺點,所以才會出現HTTPS,那麼HTTP存在哪些缺點呢?該如何解決的呢?下面來進行簡要概述
1.HTTP通訊使用明文(不加密),內容可能會被竊聽;
TCP/IP是可能被竊聽的網路:按TCP/IP協議族的工作機制,通訊內容在所有線路上都有可能遭到窺視。所以需要加密處理防止被竊聽,加密的物件如下:
(1)通訊的加密
通過和SSL(Secure Socket Layer,安全套接層)或TLS(Transport Layer Security,安全層傳輸協議)的組合使用,加密HTTP的通訊內容。用SSL建立安全通訊線路之後,就可以在這條線路上進行HTTP通訊了。與SSL組合使用的HTTP稱為HTTPS,通過這種方式將整個通訊線路加密。
(2)內容的加密
由於HTTP協議中沒有加密機制,那麼就對HTTP協議傳輸的內容本身加密。為了做到有效的內容加密,前提是要求客戶端和伺服器同時具備加密和解密機制。該方式不同於將整個通訊線路加密處理,內容仍有被篡改的風險。
2.不驗證通訊方的身份,因此有可能遭遇偽裝;
(1)任何人都可發起請求
HTTP協議不論是誰傳送過來的請求都會返回響應,因此不確認通訊方,會存在以下隱患:
1)無法確定請求傳送至目標的Web伺服器是否是按真是意圖返回響應的那臺伺服器,有可能是已偽裝的Web伺服器;
2)無法確定響應返回到的客戶端是否是按照真實意圖接收響應的那個客戶端,有可能是偽裝的客戶端;
3)無法確定正在通訊的對方是否具備訪問許可權,因為某些Web伺服器上儲存著重要的資訊,只想發給特定使用者通訊的許可權;
4)無法判斷請求是來自何方、出自誰手,即使是無意義的請求也會照單全收,無法阻止海量請求下的Dos攻擊(Denial of Service,拒絕服務攻擊)。
(2)查明對手的證照
SSL不僅提供加密處理,還使用了一種被稱為證照的手段,可用於確定通訊方。 證照由值得信任的第三方機構頒發,用以證明伺服器和客戶端是實際存在的。 使用證照,以證明通訊方就是意料中的伺服器,對使用者個人來講,也減少了個人資訊洩露的危險性。另外,客戶端持有證照即可完成個人身份的確認,也可用於對Web網站的認證環節。
3.無法證明報文的完整性,所以有可能已遭遇篡改。
在請求或響應送出之後直到對方接收之前的這段時間內,即使請求或響應的內容遭到篡改,也沒有辦法獲悉。 在請求或響應的傳輸途中,遭攻擊者攔截並篡改內容的攻擊稱為中間人攻擊(Man-in-the-Middle attack)。 僅靠HTTP確保完整性是非常困難的,便有賴於HTTPS來實現。SSL提供認證和加密處理及摘要功能。
3.3 HTTPS基礎知識點
HTTPS 並非是應用層的一種新協議。 只是 HTTP 通訊介面部分用SSL(Secure Socket Layer)和TLS(Transport Layer Security) 協議代替而已,簡言之就是HTTP+通訊加密+證照+完整性保護構成HTTPS,是身披TLS/SSL這層外殼的HTTP。
- TLS/SSL功能
TLS/SSL協議使用通訊雙方的客戶證照以及CA根證照,允許客戶/伺服器應用以一種不能被偷聽的方式通訊,在通訊雙方間建立起了一條安全的、可信任的通訊通道。
- 對稱加密和非對稱加密(公開金鑰加密)
(1)對稱加密
對稱加密指的是加密資料用的金鑰,跟解密資料用的金鑰是一樣的,使用該方法的優缺點是:
1)優點:加密、解密效率通常比較高、速度快。對稱性加密通常在訊息傳送方需要加密大量資料時使用,演算法公開、計算量小、加密速度快、加密效率高。
2)缺點:資料傳送方、資料接收方需要協商、共享同一把金鑰,並確保金鑰不洩露給其他人。此外,對於多個有資料交換需求的個體,兩兩之間需要分配並維護一把金鑰,這個帶來的成本基本是不可接受的。
(2)非對稱加密
非對稱加密指的是加密資料用的金鑰(公鑰),跟解密資料用的金鑰(私鑰)是不一樣的。公鑰就是公開的金鑰,誰都可以查到;私鑰就是非公開的金鑰,一般是由網站的管理員持有。公鑰與私鑰之間有一定聯絡:簡單來說就是,通過公鑰加密的資料,只能通過私鑰解開;通過私鑰加密的資料,只能通過公鑰解開。
- 非對稱加密(公開金鑰加密)存在的問題
非對稱加密其實是存在一些問題需要解決的,主要有以下兩個:公鑰如何獲取、資料傳輸單向安全。
- 非對稱加密中公鑰如何獲取
為了獲取公鑰,需要涉及到兩個重要概念:證照、CA(證照頒發機構),其主要用途如下:
(1)證照:可以暫時把它理解為網站的身份證。這個身份證裡包含了很多資訊,其中就包含了上面提到的公鑰。當訪問相應網站時,他就會把證照發給瀏覽器;
(2)CA:用於頒發證照,證照來自於CA(證照頒發機構)。
- 證照可能存在的問題
(1)證照是偽造的:壓根不是CA頒發的
(2)證照被篡改過:比如將XX網站的公鑰給替換了
- 證照如何防偽
數字簽名、摘要是證照防偽非常關鍵的武器。“摘要”就是對傳輸的內容,通過hash演算法計算出一段固定長度的串。然後,在通過CA的私鑰對這段摘要進行加密,加密後得到的結果就是“數字簽名”(明文 --> hash運算 --> 摘要 --> 私鑰加密 --> 數字簽名);數字簽名只有CA的公鑰才能夠解密。證照中包含了:頒發證照的機構的名字 (CA)、證照內容本身的數字簽名(用CA私鑰加密)、證照持有者的公鑰、證照籤名用到的hash演算法等。
(1)對於完全偽造的證照
這種情況對證照進行檢查
1)證照頒發的機構是偽造的:瀏覽器不認識,直接認為是危險證照
2)證照頒發的機構是確實存在的,於是根據CA名,找到對應內建的CA根證照、CA的公鑰。用CA的公鑰,對偽造的證照的摘要進行解密,發現解不了。認為是危險證照
(2)篡改過的證照
1)檢查證照,根據CA名,找到對應的CA根證照,以及CA的公鑰。
2)用CA的公鑰,對證照的數字簽名進行解密,得到對應的證照摘要AA
3)根據證照籤名使用的hash演算法,計算出當前證照的摘要BB
4)對比AA跟BB,發現不一致--> 判定是危險證照
- HTTPS問題
(1)與純文字相比,加密通訊會消耗更多的CPU及記憶體資源
1)由於HTTPS還需要做伺服器、客戶端雙方加密及解密處理,因此會消耗CPU和記憶體等硬體資源。
2)和HTTP通訊相比,SSL通訊部分消耗網路資源,而SSL通訊部分,由因為要對通訊進行處理,所以時間上又延長了。SSL慢分兩種,一種是指通訊慢;另一種是指由於大量消耗CPU及記憶體等資源,導致處理速度變慢。
(2)購買證照需要開銷。
3.4 HTTPS流程
1.客戶端發起HTTPS請求
2.服務端響應,下發證照(公開金鑰證照)
3.客戶端檢查證照,如果證照沒問題,那麼就生成一個隨機值,然後用證照(公鑰)對該隨機值進行加密。
4.將經過公鑰加密的隨機值傳送到服務端(非對稱加密),以後客戶端和伺服器的通訊就可以通過這個隨機值進行加密解密了。
5.服務端用私鑰解密後,得到了客戶端傳過來的隨機值,然後把內容通過該值進行對稱加密。
6.後期的資料傳輸都是基於該隨機值進行加密解密。
注:圖片來源於(https://blog.csdn.net/qq_3384...)