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)
}