http server雙向認證

1、客戶端認證服務器;
2、服務器認證客戶端;
3、服務器的證書使用openssl自簽名證書(我們使用server.crt就可以當做ca證書
4、客戶端的證書使用openssl自簽名證書(我們使用client.crt就可以當做ca證書

1、服務器

分析流程

1、註冊client ca證書
(1)讀取client的ca證書
(2)創建ca池,把client的ca添加到ca池
2、配置tls生成cfg
3、創建http server,使用cfg
4、啓動http server,啓動時要加載自己的證書,啓動時使用tls

代碼實現

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func main(){
	//1、註冊client ca證書
	//(1)讀取client的ca證書,client的證書也是自簽名的,自己認證自己
	caInfo,err := ioutil.ReadFile("./client.crt")
	if err != nil{
		log.Fatal(err)
	}
	//(2)創建ca池,把client的ca添加到ca池
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caInfo)
	//2、配置tls生成cfg
	cfg := tls.Config{
		//需要兩個字段,我們認證client
		ClientAuth:tls.RequireAndVerifyClientCert,
		ClientCAs:caCertPool,	//客戶端的ca池填充在這裏
	}
	//3、創建http server,使用cfg
	server := http.Server{
		Addr:":8848",
		Handler:myhandler{},
		TLSConfig:&cfg,
	}
	//4、啓動http server,啓動時要加載自己的證書,啓動時使用tls
	err = server.ListenAndServeTLS("./server.crt","./server.key")
	if err != nil{
		log.Fatal(err)
	}
}

type myhandler struct{

}

func (h myhandler)ServerHTTP(w http.ResponseWriter , r *http.Request)  {
	fmt.Printf("ServerHttp called\n")
	w.Write([]byte("hello world!!!!"))
}

2、客戶端

分析流程

1、註冊給服務器頒發證書的ca
(1)讀取ca證書
(2)把ca的證書添加到ca池中
(3)加載客戶端的證書和密鑰,得到一個clientCert(相對於單向認證,修改部分)
2、配置tls,增加clientCert(相對於單向認證,修改部分)
3、創建http client
4、client發起請求
5、打印返回值

代碼實現

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func main(){
	//1、註冊給服務器頒發證書的ca
	//(1)讀取ca證書
	caCertInfo,err:= ioutil.ReadFile("./server.crt")
	if err != nil{
		log.Fatal(err)
	}
	//(2)把ca的證書添加到ca池中
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCertInfo)
	//(3)加載客戶端的證書和密鑰,得到一個clientCert(相對於單向認證,修改部分)
	//func LoadX509KeyPair(certFile, keyFile string) (Certificate, error)
	clientCert , err := tls.LoadX509KeyPair("./client.crt","./client.key")
	if err != nil{
		log.Fatal(err)
	}
	//2、配置tls,增加clientCert(相對於單向認證,修改部分)
	cfg := tls.Config{
		//服務器的ca池
		RootCAs:caCertPool,
		//客戶端證書
		Certificates:[]tls.Certificate{clientCert},
	}
	//3、創建http client
	client := http.Client{
		Transport:&http.Transport{
			TLSClientConfig:&cfg,
		},
	}
	//4、client發起請求
	response,err := client.Get("https:localhost:8848")
	if err != nil{
		log.Fatal(err)
	}
	//5、打印返回值
	bodyInfo,err := ioutil.ReadAll(response.Body)
	if err != nil{
		log.Fatal(err)
	}
	defer response.Body.Close()
	fmt.Printf("body Info:%s\n",bodyInfo)
	fmt.Printf("status code: %s\n",response.Status)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章