# HTTP協議和HTTPS協議
Http協議是一個在計算機世界里專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規范。
請求報文格式:
~~~java
請求方法 URL 版本 \n
多個首部字段名:值 \n
\n
實體主體
~~~
主要包括:請求行、首部行、請求體。
請求方法有如下幾種方式:
- Option:請求一些選項的信息。
- get:請求讀取由URL所標志的信息。
- post:給服務器添加資源。
- head:請求讀取由URL所標志的信息的首部。
- put:修改服務器資源。
- delete:刪除指明的URL所標志的資源。
- trace:用來進行本地環回測試的請求報文。
- connect:用于代理服務器。
版本指的是HTTP的版本,現在一般都指http1.1。
響應報文格式:
~~~java
版本 狀態碼 狀態描述 \n
多個首部字段:值 \n
\n
實體主體
~~~
包括:狀態行、首部行、響應體
狀態碼分類:
- 1xx通知信息,請求收到了或正在處理。
- 2xx請求成功,常見有200,202,206。
- 3xx重定向。
- 4xx客戶端錯誤,常見有400,403,404。
- 5xx服務器錯誤,常見有500,506。
**首部行中常見字段:**
1. Host字段
用于客戶端發送請求時,指定服務器的域名。
2. Content-Length字段
服務器返回時用于表明本次響應的數據長度。
3. Connection
用于表示是否是持久化的連接,以便其他請求復用這條連接
~~~java
Connection:Keep-Alive
~~~
HTTP/1.1 版本的默認連接都是持久連接,但為了兼容?版本的 HTTP,需要指定 Connection ?部字段的值為Keep-Alive 。
4. Content-Type
請求報文中表示發送的參數的數據類型,響應報文中表示響應實體數據的數據類型。
5. Accept:\*/\*
客戶端聲明自己可以接受任何格式的數據。
## HTTPS協議
HTTP協議是明文傳輸的協議,帶來了如下幾個風險:
1. 竊聽風險:第三方可以獲知通信內容。
2. 篡改風險:第三方可以修改通信內容。
3. 冒充風險:第三方可以冒充他人身份參與通信。
由此引入了HTTPS協議:HTTPS = SSL/TLS + HTTP。
* 安全套接字層SSL (Secure Socket Layer)
* 運輸層安全TLS(Transport Layer Security)。
:-: 
> 關于信息加密的解決方案:
> 1. 最開始采用公鑰加密的方式(對稱加密),客戶端和服務器持有相同的一份密鑰,信息根據這份密鑰加密后再根據這份密鑰解密;常用的算法有:DES、AES等。但是這種做法密鑰傳輸過程中很容易被捕獲,不安全。
> 2. 之后引入了非對稱加密的方式,密鑰分為公鑰和私鑰,公鑰是公開的,私鑰是服務器私有的;信息通過公鑰加密之后只能通過私鑰解密,通過私鑰加密后只能通過公鑰解密。這種方式可以保證在加密解密的過程中是安全的,只用一對公私鑰可以保證客戶端向服務器發送的消息是可以正確被解密的,但是服務器向客戶端發送公鑰的時候容易被人截獲之后篡改公鑰信息,即中間人攻擊。才用兩對公私鑰可以保證通信的正確性,但是非對稱加密的方式是非常耗費算力資源的。
> 3. 對稱和非對稱混合加密:SSL/TLS的使用方式。
SSL/TLS采用了公鑰和私鑰混合加密的方式,其總體的思路如下:
1. 服務器往客戶端發送非對稱加密中的公鑰。
2. 客戶端拿到公鑰之后隨機生成一份**密鑰**,并用公鑰進行加密后發送給服務器。
3. 服務器拿到**密鑰**后用私鑰進行解密。
4. 之后客戶端和服務器雙方都通過這份**密鑰**進行對稱加密和解密。
這個過程只用到了一次非對稱加密和解密,這也是SSL/TLS握手過程發生的,其他正式通信都用對稱加密的方式。
兩個問題:
1. 如何保證公鑰不會被篡改?
> 將公鑰放在數字證書中,證書可信,公鑰就可信,就像身份證一樣。
2. 如何保證證書可信?
> 把證書生成一份簽名,對比證書和簽名就能發現證書是否被篡改。
:-: 
### SSL/TLS握手過程
其過程如下:
(1) 客戶端向服務器端索要并驗證公鑰。
(2) 雙方協商生成"對話密鑰"。
(3) 雙方采用"對話密鑰"進行加密通信。
前兩步稱為握手階段,該階段涉及四次通信,通信過程都是明文的,具體過程如下:
1. 客戶端發送請求(ClientHello)
發送的信息如下:
~~~java
(1) 支持的協議版本,比如TLS 1.0版。
(2) 一個客戶端生成的隨機數,稍后用于生成"對話密鑰"。
(3) 支持的加密方法,比如RSA公鑰加密。
(4) 支持的壓縮方法。
~~~
2. 服務器回應(ServerHello)
服務器收到客戶端請求后,向客戶端發出回應,這叫做SeverHello。包含如下信息:
~~~java
(1) 確認使用的加密通信協議版本,比如TLS 1.0版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信。
(2) 一個服務器生成的隨機數,稍后用于生成"對話密鑰"。
(3) 確認使用的加密方法,比如RSA公鑰加密。
(4) 服務器證書。
~~~
3. 客戶端回應
驗證服務端發送的信息并向訪問者發出提示信息,如果證書沒有問題會向服務器發送如下的信息:
~~~java
(1) 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽。
(2) 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(3) 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前
面發送的所有內容的hash值,用來供服務器校驗。
~~~
總共生成了三個隨機數用于生成“對話密鑰”。
4. 服務器最后回應
服務器收到客戶端生成的三個隨機數后,會計算生成本次回話所用的“會話密鑰”,然后向客戶端發送最后如下的消息:
~~~java
(1)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(2)服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是
前面發送的所有內容的hash值,用來供客戶端校驗。
~~~
至此,整個握手階段全部結束。接下來,客戶端與服務器進入加密通信,就完全是使用普通的HTTP協議,只不過用"會話密鑰"加密內容。
【參考】
1. https://www.zhihu.com/search?type=content&q=https
- 第一章 Java基礎
- ThreadLocal
- Java異常體系
- Java集合框架
- List接口及其實現類
- Queue接口及其實現類
- Set接口及其實現類
- Map接口及其實現類
- JDK1.8新特性
- Lambda表達式
- 常用函數式接口
- stream流
- 面試
- 第二章 Java虛擬機
- 第一節、運行時數據區
- 第二節、垃圾回收
- 第三節、類加載機制
- 第四節、類文件與字節碼指令
- 第五節、語法糖
- 第六節、運行期優化
- 面試常見問題
- 第三章 并發編程
- 第一節、Java中的線程
- 第二節、Java中的鎖
- 第三節、線程池
- 第四節、并發工具類
- AQS
- 第四章 網絡編程
- WebSocket協議
- Netty
- Netty入門
- Netty-自定義協議
- 面試題
- IO
- 網絡IO模型
- 第五章 操作系統
- IO
- 文件系統的相關概念
- Java幾種文件讀寫方式性能對比
- Socket
- 內存管理
- 進程、線程、協程
- IO模型的演化過程
- 第六章 計算機網絡
- 第七章 消息隊列
- RabbitMQ
- 第八章 開發框架
- Spring
- Spring事務
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 數據庫
- Mysql
- Mysql中的索引
- Mysql中的鎖
- 面試常見問題
- Mysql中的日志
- InnoDB存儲引擎
- 事務
- Redis
- redis的數據類型
- redis數據結構
- Redis主從復制
- 哨兵模式
- 面試題
- Spring Boot整合Lettuce+Redisson實現布隆過濾器
- 集群
- Redis網絡IO模型
- 第十章 設計模式
- 設計模式-七大原則
- 設計模式-單例模式
- 設計模式-備忘錄模式
- 設計模式-原型模式
- 設計模式-責任鏈模式
- 設計模式-過濾模式
- 設計模式-觀察者模式
- 設計模式-工廠方法模式
- 設計模式-抽象工廠模式
- 設計模式-代理模式
- 第十一章 后端開發常用工具、庫
- Docker
- Docker安裝Mysql
- 第十二章 中間件
- ZooKeeper