1、客户端认证服务器;
2、服务器不认证客户端;
3、服务器的证书使用openssl自签名证书(我们使用server.crt就可以当做ca证书)
一、服务器端
流程分析
1、创建http server
2、启动http server,启动时要加载自己的证书,启动时使用tls
生成服务器证书
使用-subject参数,指定服务器的相关信息,与之前不同,此时不许引导输入。
server证书生成:pem格式:
openssl req -x509 -nodes -newkey rsa:2048 -keyout server.key -out server.
crt -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=Global Security/OU=IT Department/CN=*"
代码展示
package main
import (
"fmt"
"log"
"net/http"
)
func main(){
//1、创建http server
server := http.Server{
//Addr string TCP address to listen on, ":http" if empty
Addr:":8848",
//Handler Handler handler to invoke, http.DefaultServeMux if nil
Handler:nil, //填写nil时,会使用默认的处理器,还是要自己实现处理逻辑
// TLSConfig optionally provides a TLS configuration for use
// by ServeTLS and ListenAndServeTLS. Note that this value is
// cloned by ServeTLS and ListenAndServeTLS, so it's not
// possible to modify the configuration with methods like
// tls.Config.SetSessionTicketKeys. To use
// SetSessionTicketKeys, use Server.Serve with a TLS Listener
// instead.
//TLSConfig *tls.Config
TLSConfig:nil,
}
//编写处理逻辑
//func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
http.HandleFunc("/",func(writer http.ResponseWriter,request *http.Request){
fmt.Println("HandleFunc!")
writer.Write([]byte("hello world!!!"))
})
//2、启动http server,启动时要加载自己的证书,启动时使用tls
//func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
err := server.ListenAndServeTLS("server.crt","server.key")
if err != nil{
log.Fatal(err)
}
}
二、客户端
分析流程
1、注册给服务器颁发证书的ca
(1)读取ca证书
(2)把ca的证书添加到ca池中
2、配置tls
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证书,我们的证书是自签名的,server.crt能够认证自己,server.crt当成CA证书
caCerInfo , err := ioutil.ReadFile("./server.crt")
if err != nil{
log.Fatal(err)
}
//(2)把ca的证书添加到ca池中
//创建ca池
certPool := x509.NewCertPool()
//添加ca到ca池中
certPool.AppendCertsFromPEM(caCerInfo)
//2、配置tls
//将承认的ca池配置给tls
cfg := tls.Config{
RootCAs:certPool,
}
//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:%s\n",bodyInfo)
fmt.Printf("status code: %s\n",response.Status)
}