https 原理與實(shí)踐

https 原理與實(shí)踐

經(jīng)典三問(wèn),是什么,為什么,怎么做?

是什么

是一種http的安全協(xié)議,在tcp ip網(wǎng)絡(luò)模型里,http應(yīng)用層是在tcp 傳輸層之上的,https協(xié)議規(guī)定了在tcp傳輸層之上還有一層tls/ssl層,這一層對(duì)http應(yīng)用層發(fā)出去和接收的報(bào)文做加密和解密。
image.png

為什么

出現(xiàn)https原因,在我看來(lái)有兩點(diǎn)

1,因?yàn)閔ttp是明文傳輸,極不安全,需要對(duì)報(bào)文進(jìn)行加密。

2,我們無(wú)法確認(rèn)瀏覽的網(wǎng)站的身份信息,如果是釣魚(yú)網(wǎng)站,誘使我們輸入銀行賬號(hào)密碼之類(lèi)的就麻煩了。

怎么做

簡(jiǎn)而言之,「https規(guī)定了 加密算法對(duì)報(bào)文進(jìn)行加密,解決明文傳輸?shù)膯?wèn)題。采用數(shù)字證書(shū)的方式解決對(duì)服務(wù)端的身份認(rèn)證問(wèn)題」。

加密報(bào)文方式

對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密

對(duì)稱(chēng)加密是加密和解密都采用同一個(gè)密鑰。 非對(duì)稱(chēng)加密 將密鑰分為公鑰和私鑰, 公鑰進(jìn)行加密的報(bào)文,用私鑰可以解密。私鑰加密的報(bào)文,用公鑰可以解密(這種加密方式也是數(shù)字證書(shū)采用的原理)

一般對(duì)稱(chēng)加密會(huì)比非對(duì)稱(chēng)加密性能高幾個(gè)數(shù)量級(jí)。但是就安全性而言,非對(duì)稱(chēng)加密安全性會(huì)更高,那么https采用的是什么加密方式呢?

兩者結(jié)合的加密方式

由于對(duì)稱(chēng)加密性能更好,所以https在真正加密報(bào)文時(shí)還是采用的對(duì)稱(chēng)加密方式,但是對(duì)稱(chēng)加密的密鑰是通過(guò)非對(duì)稱(chēng)加密協(xié)商后傳給對(duì)方的。這樣的加密方式就能保證在性能更好的前提下也有不錯(cuò)的安全性。

數(shù)字證書(shū)原理以及應(yīng)用

數(shù)字證書(shū)是什么

數(shù)字證書(shū) 是一個(gè)可信組織驗(yàn)證和簽發(fā)的識(shí)別信息。有點(diǎn)類(lèi)似于現(xiàn)實(shí)生活中的身份證,公安機(jī)關(guān)給我們頒發(fā)身份證為的就是證明個(gè)人身份,而在網(wǎng)絡(luò)世界里,這個(gè)組織就是ca組織。

來(lái)看看向ca組織提交注冊(cè)信息以及驗(yàn)證數(shù)字證書(shū)的過(guò)程。

go語(yǔ)言精進(jìn)之路截圖

go語(yǔ)言精進(jìn)之路截圖

server.key是網(wǎng)站擁有的自己的私鑰,ca.key是ca的私鑰,server.crt是網(wǎng)站的數(shù)字證書(shū)。

1,首先網(wǎng)站服務(wù)將自身的一些基本信息通過(guò)自身的私鑰進(jìn)行加密,然后將自身的公鑰和基本信息密文通過(guò)證書(shū)簽名請(qǐng)求的格式傳遞給ca。 2,ca得到請(qǐng)求后,利用網(wǎng)站服務(wù)的公鑰,對(duì)其基本信息進(jìn)行解密。然后再按x509數(shù)字證書(shū)規(guī)范生成公鑰證書(shū)。

這里涉及到ca對(duì)證書(shū)信息的加密方式,前面提到用私鑰加密的數(shù)據(jù),可用公鑰解密,當(dāng)將證書(shū)信息通過(guò)私鑰加密后,客戶(hù)端就能通過(guò)ca的公鑰去解密證書(shū),能成功解密,說(shuō)明證書(shū)的確是ca頒發(fā)的。

但實(shí)際加密卻不是這樣,因?yàn)榉菍?duì)稱(chēng)加密算法 加密的信息越多性能越差,所以是將證書(shū)信息通過(guò)摘要算法生成固定長(zhǎng)度的字符后,再采用ca私鑰對(duì)其摘要進(jìn)行加密。 摘要算法(常見(jiàn)的如MD5,sha)確保了數(shù)據(jù)的完整性,因?yàn)槎啻蜗嗤瑑?nèi)容的數(shù)據(jù)用相同摘要算法計(jì)算的結(jié)果一致,所以能基本保證數(shù)據(jù)未被篡改。

3,x509數(shù)字證書(shū)里面包含 以下信息: 服務(wù)端公鑰(server.pub); 證書(shū)相關(guān)屬性信息,如域名、有效期等; 證書(shū)頒發(fā)機(jī)構(gòu)的簽名信息 4,然后就是客戶(hù)端的解密過(guò)程,拿到證書(shū)以后,通過(guò)ca公鑰對(duì)證書(shū)以及公鑰信息的摘要密文進(jìn)行解密,得到消息摘要,然后用摘要算法對(duì)證書(shū)信息以及公鑰信息進(jìn)行摘要計(jì)算,將客戶(hù)端得到的摘要和密文解密后的摘要進(jìn)行對(duì)比,如果相同,說(shuō)明內(nèi)容未被篡改,證書(shū)有效。

數(shù)字證書(shū)的加密算法總結(jié)

通過(guò)私鑰加密,公鑰解密的方式提供證書(shū)的頒發(fā)證明,能成功解密說(shuō)明證書(shū)的確是ca頒發(fā)的。 通過(guò)摘要算法,確保了證書(shū)的完整性,未被篡改的證明。

https握手過(guò)程簡(jiǎn)析

建立在https要解決什么問(wèn)題的基礎(chǔ)上,理解https的握手過(guò)程,看看它究竟做了什么設(shè)計(jì),讓握手過(guò)程更高效,更安全。

https是為了解決明文傳輸?shù)牟话踩?,以及?duì)端身份認(rèn)證的問(wèn)題。
go語(yǔ)言精進(jìn)之路截圖

1,客戶(hù)端發(fā)送client hello信息將自身支持的tls版本,密碼套件的信息傳給服務(wù)端。

2,服務(wù)端接收后會(huì)發(fā)送server hello信息 選擇tls版本和加密算法發(fā)給客戶(hù)端。

3,然后服務(wù)端發(fā)送server certificate 信息將自身的證書(shū)下發(fā)給客戶(hù)端。

4,然后服務(wù)端接著又發(fā)送密鑰協(xié)商請(qǐng)求 server key exchange, 在密鑰協(xié)商環(huán)節(jié),通常會(huì)使用到Diffie-Hellman(DH)密鑰交換算法,這是一種密鑰協(xié)商的協(xié)議,支持通信雙方在不安全的通道上生成對(duì)稱(chēng)加密算法所需的共享密鑰。注意這種交換算法使用的目的是既讓通信雙方都擁有一樣的密鑰,但是呢,密鑰又不是通過(guò)數(shù)據(jù)傳輸?shù)綄?duì)面的,是協(xié)商產(chǎn)生的。

5 接著客戶(hù)端收到證書(shū)后,先檢驗(yàn)證書(shū)的有效性, 然后客戶(hù)端生成接下來(lái)加密通信的密鑰,同時(shí)將生成密鑰的一些參數(shù) 用服務(wù)端的公鑰加密后 發(fā)送給 服務(wù)端,這個(gè)階段稱(chēng)為client key exchange階段,服務(wù)端收到后按這些參數(shù)后用自身的私鑰解密 然后也生成相同密鑰。

6,最后客戶(hù)端和服務(wù)端分別會(huì)將連接至今的所有報(bào)文進(jìn)行加密發(fā)送給對(duì)方,以驗(yàn)證tls握手成功。

golang聲明https服務(wù)器

懂了交互邏輯以后,就知道了,聲明一個(gè)https服務(wù)的時(shí)候,得有一個(gè)ca頒發(fā)的證書(shū),證書(shū)里面包含服務(wù)端自身的公鑰信息和一些基本信息,然后還得指明明服務(wù)器的私鑰,用于tls握手過(guò)程中對(duì)密鑰協(xié)商參數(shù)的加解密。

package main

import (
    // "fmt"
    // "io"
    "net/http"
    "log"
)

func HelloServer(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("This is an example server.\n"))
    // fmt.Fprintf(w, "This is an example server.\n")
    // io.WriteString(w, "This is an example server.\n")
}

func main() {
    http.HandleFunc("/hello", HelloServer)
    err := http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

基于上述https原理,下面我將會(huì)用openssl 工具以及golang程序來(lái)演示下https加解密過(guò)程。

生成服務(wù)器私鑰

openssl genrsa -out server.key 2048

生成x509證書(shū)

openssl req -new -x509  -key server.key -out server.crt -days 3650

server.crt 就是我們的自簽名證書(shū)了,然后啟動(dòng)go https服務(wù)

啟動(dòng)go https服務(wù)

package main

import (
 "log"
 // "fmt"
 // "io"
 "net/http"
)

func HelloServer(w http.ResponseWriter, req *http.Request) {
 w.Header().Set("Content-Type", "text/plain")
 w.Write([]byte("This is an example server.\n"))
 // fmt.Fprintf(w, "This is an example server.\n")
 // io.WriteString(w, "This is an example server.\n")
}

func main() {
 http.HandleFunc("/hello", HelloServer)
 err := http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
 if err != nil {
  log.Fatal("ListenAndServe: ", err)
 }
}

先測(cè)試下訪問(wèn)

(base) ?  ~ curl https://proxy.example.com:443/hello
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl 提示是自簽名證書(shū),因?yàn)槲覀兪褂玫膐penssl 按x509標(biāo)準(zhǔn)生成的證書(shū),不是ca頒發(fā)的,所以curl有這個(gè)錯(cuò)誤。

讓系統(tǒng)信任該證書(shū)

不同操作系統(tǒng)添加信任的方式不同,我使用的是mac os,在鑰匙串應(yīng)用里將證書(shū)添加進(jìn)來(lái)并設(shè)置為信任。
image.png

注意這里我設(shè)置了證書(shū)的域名是proxy.example.com ,所以我還需要設(shè)置下這個(gè)域名對(duì)應(yīng)的ip

設(shè)置域名

vim /etc/hosts

255.255.255.255 broadcasthost
127.0.0.1       localhost
::1             localhost

## 添加上這行
127.0.0.1 proxy.example.com

再次訪問(wèn)

(base) ?  ~ curl https://proxy.example.com:443/hello
This is an example server.

發(fā)現(xiàn)當(dāng)前訪問(wèn)已經(jīng)成功了。

完美收工。。。

參考文獻(xiàn): go 語(yǔ)言精進(jìn)之路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文中首先解釋了加密解密的一些基礎(chǔ)知識(shí)和概念,然后通過(guò)一個(gè)加密通信過(guò)程的例子說(shuō)明了加密算法的作用,以及數(shù)字證書(shū)的出現(xiàn)...
    Healer_8閱讀 558評(píng)論 0 0
  • 在說(shuō)htttps 之前,我們先了解一下加密,會(huì)對(duì)后面說(shuō)https 好理解一點(diǎn) 一 加密方式 加密按照加密方式,可以...
    度憨憨閱讀 418評(píng)論 0 1
  • 網(wǎng)上對(duì)一些關(guān)于對(duì)稱(chēng)加密、非對(duì)稱(chēng)加密、數(shù)字簽名、數(shù)字證書(shū)等文章雖然很多,但是沒(méi)有深入研究過(guò)或者看過(guò)一點(diǎn)的人過(guò)段時(shí)間很...
    WEIJAVA閱讀 696評(píng)論 0 1
  • HTTPS 是在 HTTP 和 TCP 之間建立了一個(gè)安全層,HTTP 與 TCP 通信的時(shí)候,必須先進(jìn)過(guò)一個(gè)安全...
  • 文章結(jié)構(gòu) 感人小故事: 通過(guò)故事,說(shuō)一說(shuō)為什么要加密。 密碼學(xué): 單鑰加密&雙鑰加密。 數(shù)字簽名&數(shù)字證書(shū)&證書(shū)授...
    Mccc_閱讀 5,497評(píng)論 2 11

友情鏈接更多精彩內(nèi)容