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