簡單過程
以chrome和bilibili網站通信爲例:
前提:bilibili向CA機構申請證書
首先是bilibili將自己的信息和公鑰放置到證書,然後向CA提交申請,CA覈實確實bilibili身份後用自己的私鑰對證書進行簽名
使用chrome向bilibili發起請求
- 瀏覽器向服務器發起請求
- 服務器響應請求,將CA證書發給瀏覽器
- 瀏覽器獲取內置的CA公鑰對證書上的簽名進行驗證,證明服務器的身份(即驗證公鑰是不是bilibili的),驗證成功後獲取證書上的公鑰
- 瀏覽器生成一段隨機數,並使用服務器公鑰進行加密(只有bilibili服務器私鑰才能解開),發送給服務器
- 服務器收到信息後用自己的私鑰解密,獲得隨機數,之後使用這一串隨機數作爲堆成密鑰和瀏覽器進行對稱加密傳輸(對稱密鑰只有瀏覽器和服務器知道)
詳細過程
1. 身份認證
- 瀏覽器向服務器發起請求,帶上一個隨機數
client Random
- 服務器響應請求,將一個隨機數
server Random
和CA證書
發給瀏覽器 - 瀏覽器獲取
內置的CA公鑰
對證書上的簽名
進行驗證,證明服務器的身份(即驗證公鑰是不是bilibili的),驗證成功後獲取證書上的公鑰serverPublicKey
2. 密鑰協商
- 服務器生成
服務器DH參數
,並且使用自己的私鑰簽名,發給客戶端 - 客戶端收到後使用服務器公鑰
serverPublicKey
驗證簽名,獲取服務器DH參數
- 客戶端生成
客戶端DH參數
,發給服務端 - 服務端收到
客戶端DH參數
3. 對稱加密傳輸
- 服務端和客戶端此時均有
client Random
、server Random
、客戶端DH參數
、服務器DH參數
,將四者進行結合生成對稱密鑰,然後通過對稱密鑰進行加密傳輸
補充
1. TLS/SSL
2. RSA非對稱加密原理
/* p,q爲兩個質數 */
let p = 3, q = 11;
let fN = (p - 1) * (q - 1);
/* 公鑰 {e,N} */
let e = 7;
let N = p * q;//33
let publicKey = { e, N };
/* 私鑰{d,N} */
let d = 1;
while (e * d % fN !== 1) d++;
console.log(d);//3
let privateKey = { d, N };
/* ------------ 測試 ------------ */
/* 公鑰加密 */
let m = 5;
let c = Math.pow(m, publicKey.e) % publicKey.N;//c = m^e % N
console.log('c = ' + c);//c=14
/* 私鑰解密 */
let origin = Math.pow(c, privateKey.d) % privateKey.N;//m = c^d % N
console.log(origin);//5
3. Diffie-Heliman原理
/* 公共部分 */
let p = 5, N = 23;
/* A,B各自的密鑰 */
let secretA = 6, secretB = 15;
/* A加密 */
let A = Math.pow(p, secretA) % N;
console.log("A = " + A);
/* B加密 */
let B = Math.pow(p, secretB) % N;
console.log("B = " + B);
/* A將A給B,B將B給A */
//A解密
console.log(Math.pow(B, secretA) % N);//2
//B解密
console.log(Math.pow(A, secretB) % N)//2