GO实现数字证书HTTPS双向认证
HTTPS知识点全部的分析代码 anli.zip DOWNLOAD
本案例证书双向的客户端生成有点问题 无法校验成功
报错
2021/10/04 11:00:47 Get “https://localhost:8849”: remote error: tls: bad certificate
服务器
-分析流程
1. 注册client ca证书 - 读取client的ca证书 - 创建ca池 - 把client 的 ca 添加到ca池 2. 配置tls ==> cfg 3. 创建http server, 使用cfg 4. 启动http server,启动时加载自己的证书, 启动时使用tls
客户端
1. 注册给服务器颁发证书的ca - 读取ca证书 - 把ca的证书添加到ca池中 1.5 加载客户端的证书和秘钥 ==> clientCert(与单向认证比较增加代码) 2. 配置tls, ==》 增加clientCert(与单向认证比较增加代码) 3.创建http client 4. client发起请求 5. 打印返回值
https-server.go
package main import ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "log" "net/http" ) func main() { // 注册读取client CA证书 caInfo,err := ioutil.ReadFile("./client.pem") if err != nil{ log.Fatal(err) } //创建CA池 certPool := x509.NewCertPool() //把client的ca添加到ca池 certPool.AppendCertsFromPEM(caInfo) //配置tls cfg := tls.Config{ // 我们要认证client, 需要两个字段 // ClientAuth determines the server's policy for // TLS Client Authentication. The default is NoClientCert. //ClientAuth ClientAuthType // const ( // NoClientCert ClientAuthType = iota // RequestClientCert // RequireAnyClientCert // VerifyClientCertIfGiven // RequireAndVerifyClientCert //) ClientAuth: tls.RequireAndVerifyClientCert, //设置服务器认证客户端 ClientCAs: certPool,//客户端的ca池填充在这里 } //使用cfg创建hhtpserver server := http.Server{ Addr: ":8849", //Handler: nil, Handler: &myhandler{}, TLSConfig: &cfg, } fmt.Println("准备启动服务器") err = server.ListenAndServeTLS("./server.pem","./server.key") if err != nil{ log.Fatal(err) } } type myhandler struct { } //注意 ServeHTTP 大小写不能写错 func (h myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Println("ServeHTTP called!") w.Write([]byte("Hello World")) }
https-client
package main import ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "log" "net/http" ) func main() { //注册给服务器颁发证书的ca //读取CA证书 caInfo,err := ioutil.ReadFile("./server.pem") if err != nil{ log.Fatal(err) } //把CA证书添加到CA池中 certPool := x509.NewCertPool() //添加 certPool.AppendCertsFromPEM(caInfo) //加载客户端的证书和秘钥 <与单向认证代码不同的区域> clientCert,err := tls.LoadX509KeyPair("./client.pem","./client.key") if err != nil{ log.Fatal(err) } //配置cls <与单向认证代码不同的区域> cfg := tls.Config{ //服务器ca池 RootCAs: certPool, //客户端证书 Certificates: []tls.Certificate{clientCert}, } //创建http client := http.Client{ Transport: &http.Transport{ TLSClientConfig: &cfg, }, } //发送client请求 response,err := client.Get("https://localhost:8849") if err != nil{ log.Fatal(err) } defer response.Body.Close() bodyInfo,err :=ioutil.ReadAll(response.Body) if err != nil{ log.Fatal(err) } fmt.Printf("body info:%s\n",bodyInfo) fmt.Printf("State:%s\n",response.Status) }