Golang學(xué)習(xí)筆記之HTTPS

一:HTTPS介紹

HTTPS (Secure Hypertext Transfer Protocol)安全超文本傳輸協(xié)議,是一個(gè)安全通信通道,它基于HTTP開發(fā)用于在客戶計(jì)算機(jī)和服務(wù)器之間交換信息碴倾。它使用安全套接字層(SSL)進(jìn)行信息交換偎漫,簡(jiǎn)單來說它是HTTP的安全版,是使用TLS/SSL加密的HTTP協(xié)議穆咐。

HTTP和HTTPS的區(qū)別

? HTTPS是加密傳輸協(xié)議耕陷,HTTP是名文傳輸協(xié)議
? HTTPS需要用到SSL證書,而HTTP不用
? HTTPS比HTTP更加安全辙喂,對(duì)搜索引擎更友好捶牢,利于SEO
? HTTPS標(biāo)準(zhǔn)端口443,HTTP標(biāo)準(zhǔn)端口80
? HTTPS基于傳輸層巍耗,HTTP基于應(yīng)用層
? HTTPS在瀏覽器顯示綠色安全鎖秋麸,HTTP沒有顯示

二、HTTPS證書

正式發(fā)布的時(shí)候炬太,是需要購買正規(guī)的證書的竹勉。測(cè)試程序時(shí),如果沒有娄琉,我們可以使用openssl來生成私人的證書。

(1)首先我們先生成證書私鑰

openssl genrsa -out server.key 2048

(2)根據(jù)私鑰生成公鑰

openssl rsa -in server.key -out server.key.public

(2)根據(jù)私鑰生成證書

openssl req -new -x509 -key server.key -outserver.crt -days 365
注意以上命令是生成在當(dāng)前文件夾下的

三吓歇、Golang實(shí)現(xiàn)HTTPS程序

第一個(gè)HTTPS程序

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w,
        "Hi, This is an example of https service in golang!")
}
func main1() {
    http.HandleFunc("/", handler)
    //https監(jiān)聽孽水,必須提供證書文件和對(duì)應(yīng)的私鑰文件。
    http.ListenAndServeTLS(":8081", "server.crt",
        "server.key", nil)
}

瀏覽器輸入 https://127.0.0.1:8081進(jìn)行測(cè)試即可城看。
注意瀏覽器會(huì)提示此鏈接不安全女气,繼續(xù)訪問即可,因?yàn)檫@個(gè)證書使我們自己生成的测柠,并不被瀏覽器所承認(rèn)炼鞠。上面兩個(gè)文件的路徑可以是絕對(duì)路徑也可以相對(duì),這里在同一文件夾下使用的

四轰胁、訪問自己的HTTPS服務(wù)端

go實(shí)現(xiàn)的Client端默認(rèn)也是要對(duì)服務(wù)端傳過來的數(shù)字證書進(jìn)行校驗(yàn)的谒主,因?yàn)槲覀兊淖C書并不是知名CA簽發(fā)的。所以我們要跳過驗(yàn)證赃阀,如下

func main() {
    //要管理代理霎肯、TLS配置、keep-alive、壓縮和其他設(shè)置观游,創(chuàng)建一個(gè)Transport
    //Client和Transport類型都可以安全的被多個(gè)go程同時(shí)使用搂捧。出于效率考慮,應(yīng)該一次建立懂缕、盡量重用允跑。
    tr := &http.Transport{
        //InsecureSkipVerify用來控制客戶端是否證書和服務(wù)器主機(jī)名。如果設(shè)置為true,
        //則不會(huì)校驗(yàn)證書以及證書中的主機(jī)名和服務(wù)器主機(jī)名是否一致搪柑。
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://localhost:8081")
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
五聋丝、對(duì)服務(wù)端證書進(jìn)行校驗(yàn)

多數(shù)時(shí)候,我們需要對(duì)服務(wù)端的證書進(jìn)行校驗(yàn)拌屏,而不是像上面那樣忽略這個(gè)校驗(yàn)潮针。

首先我們來建立我們自己的CA,需要生成一個(gè)CA私鑰和一個(gè)CA的數(shù)字證書:
(1)生成CA私鑰

openssl genrsa -out ca.key 2048

(2)生成CA證書

openssl req -x509 -new -nodes -key ca.key -subj "/CN=tonybai.com" -days 5000 -out ca.crt

接下來倚喂,生成server端的私鑰每篷,生成數(shù)字證書請(qǐng)求,并用我們的ca私鑰簽發(fā)server的數(shù)字證書:
(1)生成服務(wù)端私鑰

openssl genrsa -out server.key 2048

(2)生成證書請(qǐng)求文件

openssl req -new -key server.key -subj "/CN=localhost" -out server.csr

(3)根據(jù)CA的私鑰和上面的證書請(qǐng)求文件生成服務(wù)端證書

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
client.go

//客戶端對(duì)服務(wù)器校驗(yàn)
func main() {
    //CertPool代表一個(gè)證書集合/證書池端圈。
    //創(chuàng)建一個(gè)CertPool
    pool := x509.NewCertPool()
    caCertPath := "/Users/zt/GOProject/src/https/ca.crt"
    //調(diào)用ca.crt文件
    caCrt, err := ioutil.ReadFile(caCertPath)
    if err != nil {
        fmt.Println("ReadFile err:", err)
        return
    }
    //解析證書
    pool.AppendCertsFromPEM(caCrt)
    
    tr := &http.Transport{
        ////把從服務(wù)器傳過來的非葉子證書焦读,添加到中間證書的池中,使用設(shè)置的根證書和中間證書對(duì)葉子證書進(jìn)行驗(yàn)證舱权。
        TLSClientConfig: &tls.Config{RootCAs: pool},
    }
    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://localhost:8081")
    if err != nil {
        fmt.Println("Get error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

? Key 是私用密鑰openssl矗晃,通常是rsa算法
? Csr 是證書請(qǐng)求文件,用于申請(qǐng)證書宴倍。在制作csr文件的時(shí)张症,必須使用自己的私鑰來簽署,還可以設(shè)定一個(gè)密鑰
? crt是CA認(rèn)證后的證書文鸵贬,簽署人用自己的key給你簽署的憑證

六俗他、對(duì)客戶端證書進(jìn)行校驗(yàn)

要對(duì)客戶端數(shù)字證書進(jìn)行校驗(yàn),首先客戶端需要先有自己的證書阔逼。
我們以上面的例子為基礎(chǔ)兆衅,生成客戶端的私鑰與證書。

(1)生成client私鑰

openssl genrsa -out client.key 2048

(2)生成client請(qǐng)求文件

openssl req -new -key client.key -subj "/CN=tonybai_cn" -out client.csr

(3)生成client證書

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 5000
client.go

type myhandler struct {
}

func (h *myhandler) ServeHTTP(w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprintf(w,
        "Hi, This is an example of http service in golang!\n")
}
func main() {
    pool := x509.NewCertPool()
    caCertPath := "ca.crt"
    caCrt, err := ioutil.ReadFile(caCertPath)
    if err != nil {
        fmt.Println("ReadFile err:", err)
        return
    }
    pool.AppendCertsFromPEM(caCrt)
    s := &http.Server{
        Addr:    ":8081",
        Handler: &myhandler{},
        TLSConfig: &tls.Config{
            ClientCAs:  pool,
            ClientAuth: tls.RequireAndVerifyClientCert,
        },
    }
    err = s.ListenAndServeTLS("server.crt", "server.key")
    if err != nil {
        fmt.Println("ListenAndServeTLS err:", err)
    }
}

server.go

func main() {
    pool := x509.NewCertPool()
    caCertPath := "ca.crt"
    caCrt, err := ioutil.ReadFile(caCertPath)
    if err != nil {
        fmt.Println("ReadFile err:", err)
        return
    }
    pool.AppendCertsFromPEM(caCrt)
    cliCrt, err := tls.LoadX509KeyPair("client.crt", "client.key")
    if err != nil {
        fmt.Println("Loadx509keypair err:", err)
        return
    }
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            RootCAs:      pool,
            Certificates: []tls.Certificate{cliCrt},
        },
    }
    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://localhost:8081")
    if err != nil {
        fmt.Println("Get error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
HTTPS要使客戶端與服務(wù)器端的通信過程得到安全保證,必須使用的對(duì)稱加密算法,但是協(xié)商對(duì)稱加密算法的過程唱逢,需要使用非對(duì)稱加密算法來保證安全,然而直接使用非對(duì)稱加密的過程本身也不安全畏铆,會(huì)有中間人篡改公鑰的可能性,所以客戶端與服務(wù)器不直接使用公鑰吉殃,而是使用數(shù)字證書簽發(fā)機(jī)構(gòu)頒發(fā)的證書來保證非對(duì)稱加密過程本身的安全及志。這樣通過這些機(jī)制協(xié)商出一個(gè)對(duì)稱加密算法片排,就此雙方使用該算法進(jìn)行加密解密。從而解決了客戶端與服務(wù)器端之間的通信安全問題速侈。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末率寡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子倚搬,更是在濱河造成了極大的恐慌冶共,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,222評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件每界,死亡現(xiàn)場(chǎng)離奇詭異捅僵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)眨层,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門庙楚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人趴樱,你說我怎么就攤上這事馒闷。” “怎么了叁征?”我有些...
    開封第一講書人閱讀 157,720評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵纳账,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我捺疼,道長(zhǎng)疏虫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,568評(píng)論 1 284
  • 正文 為了忘掉前任啤呼,我火速辦了婚禮卧秘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘官扣。我一直安慰自己翅敌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評(píng)論 6 386
  • 文/花漫 我一把揭開白布醇锚。 她就那樣靜靜地躺著,像睡著了一般坯临。 火紅的嫁衣襯著肌膚如雪焊唬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評(píng)論 1 290
  • 那天看靠,我揣著相機(jī)與錄音赶促,去河邊找鬼。 笑死挟炬,一個(gè)胖子當(dāng)著我的面吹牛鸥滨,可吹牛的內(nèi)容都是我干的嗦哆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,028評(píng)論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼婿滓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼老速!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凸主,我...
    開封第一講書人閱讀 37,773評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤橘券,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卿吐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旁舰,經(jīng)...
    沈念sama閱讀 44,220評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評(píng)論 2 327
  • 正文 我和宋清朗相戀三年嗡官,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了箭窜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衍腥,死狀恐怖磺樱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情紧阔,我是刑警寧澤坊罢,帶...
    沈念sama閱讀 34,360評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站擅耽,受9級(jí)特大地震影響活孩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乖仇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評(píng)論 3 315
  • 文/蒙蒙 一憾儒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乃沙,春花似錦起趾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜀铲,卻和暖如春边琉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背记劝。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工变姨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厌丑。 一個(gè)月前我還...
    沈念sama閱讀 46,433評(píng)論 2 360
  • 正文 我出身青樓定欧,卻偏偏與公主長(zhǎng)得像渔呵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砍鸠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于https背景知識(shí)密碼學(xué)的一些基本知識(shí) 大致上分為兩類扩氢,基于key的加密算法與不基于key的加密算法。現(xiàn)在的算...
    黑手黨老k閱讀 3,995評(píng)論 0 2
  • 1.明確https域名睦番,如:tomcat.loc类茂,生成證書時(shí)使用 2.創(chuàng)建證書目錄 //進(jìn)入tmp目錄 cd /h...
    _伽藍(lán)寺聽雨聲閱讀 2,016評(píng)論 0 6
  • 001 下班回來后,取了個(gè)快遞托嚣,然后下樓剪了個(gè)頭發(fā)巩检。上次剪頭發(fā)就是在那家店,挺好看示启,今天繼續(xù)在這家店剪兢哭。不過,今天...
    文小輝cool閱讀 204評(píng)論 3 1
  • 很久沒給你寫過信了吧夫嗓,沒想到迟螺,在21世紀(jì)的今天,我卻還是喜歡寫信的方式舍咖。 今天是端午節(jié)矩父,如果沒記錯(cuò)的話,明天是你的...
    箬茶閱讀 1,062評(píng)論 11 7