構造HTTP請求
1)開發中,前后端交互。瀏覽器運行的網頁中,構造出HTTP請求
2)調試階段,通過構造HTTP請求測試服務器
樸素的方案:
通過tcp socket 的方式構造HTTP請求
按照HTTP請求格式,往TCP socket中寫入字符串,就能夠構造出HTTP請求
package HttpFile;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class HttpClient {private Socket socket = null;//初始化socketpublic HttpClient(String host, int port) {try {socket = new Socket(host, port);} catch (IOException e) {e.printStackTrace();}}//通過get方法發起一個HTTP GET請求public void get(String url) throws IOException {//構造HTTP結構的字符串try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream();){String firstLine = "GET " + url + " HTTP/1.1\n";String header = "Host: " + socket.getInetAddress().getHostAddress() +":"+socket.getPort()+ "\n";String blankLine = "\n";String httpRequest = firstLine + header + blankLine;outputStream.write(httpRequest.getBytes());outputStream.flush();//發送出請求之后,還需要讀取響應byte[] buffer = new byte[1024+1024];int n = inputStream.read(buffer);String httpResponse = new String(buffer, 0, n);System.out.println(httpResponse);}catch(IOException e){e.printStackTrace();}return ;}public static void main(String[] args) {}
}
想運行測試是有一定困難的,因為目前沒有http的服務器。sougou,baidu都是https的服務器(這一直要等到虛了spring,自己寫HTTP服務器之后)。這里主要是去理解,HTTP協議的本質就是按照格式構造字符串。
更希望的是構造出HTTPS的請求來訪問一些知名的網站,但是通過tcp socket構造非常復雜,然而也有一些現成的庫。
Java / Python /C++ 主流的編程語言都提供了這樣的庫。
HTTPS加密流程詳解
?一、HTTPS基礎概念
HTTPS(HyperText Transfer Protocol Secure)是HTTP的安全版本,它在傳輸層和應用層之間加入了SSL/TLS加密層。主要特點包括:
1. 數據加密:防止傳輸內容被竊聽
2. 身份驗證:確保通信雙方的真實性
3. 數據完整性:防止傳輸內容被篡改
二、HTTPS加密流程詳解
HTTP是明文傳輸的,因此HTTP并不安全,容易發生“運營商劫持”,如下圖
運營商的路由器,搭載一些程序,識別到如果是要獲取天天動聽的下載地址,那么就篡改成QQ瀏覽器的下載地址
這就涉及到了“加密”的概念。加密屬于密碼學,密碼學屬于數學的分支學科。
其中,比較基礎的核心概念:
明文:要傳輸的原始數據
密文:要保護原始數據,需要對數據進行變化,使其不容易被別人識別出來
明文->密文:加密過程
密文->明文:解密過程
加密解密過程中涉及到一個關鍵的中間數據:密鑰
HTTPS工作過程:(這里不研究加密的具體算法是怎么做到的,因為這是一個比較復雜的數學問題)
1.引入對稱加密
生成一個密鑰,明文到密文,通過這個密鑰進行,而密文到明文,也是通過這個密鑰來進行的。此時客戶端給服務器發送的就是通過key進行對稱加密的密文,黑客就算知道數據是什么,由于他沒有密鑰,也就無法知道明文。
服務器收到數據之后,使用同樣的密鑰對數據進行解密。
HTTP協議來說,首航不加密,header和body都進行加密
上述方案是不太可行的。
一個服務器要給很多個客戶端提供服務,而服務器和這些客戶端通信的過程中,使用的密鑰不是同一個。既然每個客戶端的密鑰都是不同的,得有人生成一個“隨機的密鑰”來作為這次通信使用,可以是客戶端負責生成,也可以是由服務器負責生成。無論是哪一方生成,都需要去通知對方。
客戶端負責生成密鑰,比如888888(真實的密鑰是非常長的一串字符串)
上述的密鑰傳輸,也經過了黑客的設備,黑客也就知道了
問題:需要告訴對方密鑰是什么,但是密鑰不能明文傳輸
那么,如果對密鑰再進行一次對稱加密呢?比如密鑰是key,使用另一個密鑰key2針對key來進行加密,把key密文傳輸給對端。
然而,如果不把key2告訴服務器,服務器也就解密不了,拿不到key,如果把key2告訴服務器,又會被黑客獲取到。
2.引入非對稱加密
非對稱加密有兩個密鑰,這兩個密鑰其中一個可以公開出去,誰都能獲得,是公鑰
另一個則不能公開,自己持有,是私鑰
比如,使用公鑰加密,那就使用私鑰解密
如果使用私鑰加密,那就使用公鑰解密
公鑰私鑰不是憑空來的,都是數學家們研究出來的,具有一定關系的數據。
對稱加密保護數據,本身比較安全的,關鍵是對稱密鑰要能安全傳輸給對方
引入非對稱加密的主要目的,就是為了傳輸對稱密鑰
為什么不直接那非對稱加密去傳輸數據呢?
因為非對稱加密,加密解密的計算成本,遠高于對稱加密。
公鑰私鑰,是服務器生成的一個密鑰對,私鑰服務器自己持有,公鑰公開出去,所有人都能獲取得到。
客戶端就可以使用公鑰,對對稱密鑰進行加密。
當前的數據,到達黑客的設備,黑客沒有辦法,黑客手里只有公鑰,公鑰此處是用來加密的,無法進行解密。
服務器拿著私鑰解密,獲取到對稱密鑰888888
*黑客為什么不直接入侵服務器,這樣不就能拿到私鑰了嗎
*當然有可能的,?但是存在門檻的。?入侵運營商的設備,大概率是比入侵一個企業的機房要更容易一些。?直接入侵了,不需要監聽任何數據,直接拖數據庫。?(知名網站被拖庫,也不是什么新鮮事了...)
3.中間人共計
黑客是有辦法解決剛才那一套方案的?
由于公鑰本身就是公開的,不需要加密傳輸
黑客自己生成了一堆公鑰私鑰pub2 / pri2
客戶端不知道公鑰是不是對的,只能選擇相信,拿著pub2對堆成密鑰888888進行加密。
由于此時數據是通過Pub2加密的,所以黑客就可以拿著pri2對數據解密從而拿到888888.黑客手里拿到了服務器的Pub1公鑰,拿著pub1對888888重新進行加密。
服務器拿著Pri1解密,當然解密成功了,服務器拿到了888888.
4.引入證書,通過證書解決中間人共計
證書解決的核心問題,就是讓客戶端能夠識別出當前的公鑰,是否是服務器本身創建的,還是黑客偽造的
此時需要引入第三方公正機構,通過公證機構的認證就可以認為公鑰是可信的。
證書中結構化數據構成的字符串包含以下屬性:
1.證書的發布機構
2.證書的有效期
3.證書的所有者
4.證書對應服務器的地址/域名
5.公鑰(服務器生成的pub1 / pri1)
6.數字簽名
數字簽名是驗證證書有效的關鍵要素!
服務器的開發者需要再公正機構申請證書,提交資質,讓對方進行審核。
客戶端需要驗證證書的合法性,依靠數字簽名。
數字簽名的生成:
(數字簽名,就是加密后的校驗和)
公證機構,生成證書之后,針對證書,算一個校驗和
公證機構,拿著自己生成的非對稱密鑰對 (pub3 / pri3)
使用其中的 私鑰 pri3 對校驗和進行加密,得到了數字簽名。
數字簽名的驗證:
客戶端拿到證書之后,需要按照同樣的校驗和算法,對證書的這些字段 再算一次校驗和,得到checksum1 (客戶端自己算的)
使用公證機構的 pub3 公鑰對證書中的數字簽名,進行解密,得到checksum2 (公證機構算的)
如果兩者相等,說明證書沒有被篡改過,證書中的公鑰就是科學的 (服務器原始生成的)
如果黑客篡改了證書中的 公鑰,算出來的 checksum1 一定是不等于 checksum2 的
如果不匹配,客戶端/瀏覽器,彈出提示框
對于chrome 彈出 紅色的頁面 該網站存在風險,是否要繼續訪問
上述流程中
1) 黑客能否篡改公鑰呢?
不能。一旦篡改公鑰,checksum對不上,客戶端就能識別出來。?
2) 黑客能否自己搞一個證書,整個替換掉服務器返回的證書?
不能 。證書中包含了服務器的 地址/域名 本來訪問百度網站,得到的域名,是別人的域名,瀏覽也很容易識別
3) 黑客是否可以篡改公鑰同時,也把數字簽名也篡改了呢?
?不能. 數字簽名是通過公證機構的私鑰來進行加密的,這個私鑰,黑客拿不到(黑客無法對自己算的校驗和進行正確的加密)
4) 公證機構的公鑰如何被客戶端拿到? 黑客是否可能偽造公證機構的公鑰呢?
不能的!?公證機構的公鑰不是通過網絡獲取的,而是內置在操作系統里的 (當然也可以通過其他途徑進行安裝)
如果黑客搞了一個有貓膩的系統鏡像 (之前第三方的系統鏡像,大白菜,老毛桃..... 都可能存在這樣的隱患)
fiddler安裝的時候,也需要安裝一個證書。
fiddler的工作過程,就是在進行中間人攻擊。數據是加密的,信任安裝fiddler的證書,就是允許fiddler進行中間人攻擊。 fiddler使用自己的證書替換掉服務器返回的證書。 fiddler的證書已經被安裝信任了,就不會讓瀏覽器報錯了。fiddler通過上述中間人攻擊,拿到對稱密鑰,進一步的對所有數據解密 讓我們看到抓包結果的。