server端代码
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
)
/**
参考:https://www.cnblogs.com/pzblog/p/9088286.html
-----不推荐-----
-----生成的是自签名证书,客户端无法验证证书的真伪-----
openssl genrsa -out server.key 2048
openssl req -new -x509 -key server.key -out server.crt -days 365
-----推荐!!!-----
*生成CA证书(在key_file文件夹下执行)
openssl genrsa -out server_ca.key 2048
openssl req -x509 -new -nodes -key server_ca.key -subj "/CN=masa.masaAdminRegistry.notars" -days 3650 -out server_ca.crt
*生成server私匙和证书
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=masa.masaAdminRegistry.notars" -out server.csr
openssl x509 -req -in server.csr -CA server_ca.crt -CAkey server_ca.key -CAcreateserial -out server.crt -days 3650
*/
func main() {
//ignoreClientCertificate()
verifyClientCertificate()
}
/**
客户端验证服务端的证书、客户端不验证服务端的证书, 但是服务端不验证客户端的证书
*/
func ignoreClientCertificate() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
_, _ = fmt.Fprintf(writer, "Hi, This is an example of https service in golang!")
})
_ = http.ListenAndServeTLS(":8080", "key_file/server.crt", "key_file/server.key", nil)
}
/**
客户端验证服务端的证书,服务端也验证客户端的证书
*/
func verifyClientCertificate() {
caCertPath := "key_file/client_ca.crt"
caCrt, err := ioutil.ReadFile(caCertPath)
if err != nil {
fmt.Println("ReadFile err:", err)
return
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(caCrt)
serveMux := new(http.ServeMux)
serveMux.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
_, _ = fmt.Fprintf(w, "Hello\n")
})
s := &http.Server{
Addr: ":8080",
Handler: serveMux,
TLSConfig: &tls.Config{
ClientCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
},
}
//这里会阻塞,除非出错
err = s.ListenAndServeTLS("key_file/server.crt", "key_file/server.key")
if err != nil {
fmt.Println("ListenAndServeTLS err:", err)
}
}
client端
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
)
//这里不能填ip, 需要修改hosts文件
//C:\Windows\System32\drivers\etc\hosts
//127.0.0.1 masa.masaAdminRegistry.notars
var reqUrl = "https://masa.masaAdminRegistry.notars:8080"
func main() {
//ignoreServerCertificate()
//verifyServerCertificate()
verifyCertificate()
}
/**
客户端不验证服务端的证书
*/
func ignoreServerCertificate() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
client := &http.Client{
Transport: tr,
}
resp, err := client.Get(reqUrl)
if err != nil {
fmt.Println("error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
/**
客户端验证服务端的证书
*/
func verifyServerCertificate() {
caCertPath := "key_file/server_ca.crt"
caCrt, err := ioutil.ReadFile(caCertPath)
if err != nil {
fmt.Println("ReadFile err:", err)
return
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(caCrt)
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
},
}
client := &http.Client{Transport: tr}
resp, err := client.Get(reqUrl)
if err != nil {
fmt.Println("Get error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
/**
客户端验证服务端的证书,服务端也验证客户端的证书
openssl genrsa -out client_ca.key 2048
openssl req -x509 -new -nodes -key client_ca.key -subj "/CN=masa.masaAdminRegistry.client" -days 3650 -out client_ca.crt
生成客户端自身的证书(在key_file文件夹下执行)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=masa.masaAdminRegistry.client" -out client.csr
openssl x509 -req -in client.csr -CA client_ca.crt -CAkey client_ca.key -CAcreateserial -out client.crt -days 3650
生成pfx证书,用于双向认证时浏览器提供给服务器的证书
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt
*/
/**忽略
openssl x509 -req -in client.csr -CA server_ca.crt -CAkey server_ca.key -CAcreateserial -extfile ../client/client.ext -out client.crt -days 3650
client.ext文件中的内容
extendedKeyUsage=clientAuth
*/
func verifyCertificate() {
caCertPath := "key_file/server_ca.crt"
caCrt, err := ioutil.ReadFile(caCertPath)
if err != nil {
fmt.Println("ReadFile err:", err)
return
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(caCrt)
cliCrt, err := tls.LoadX509KeyPair("key_file/client.crt", "key_file/client.key")
if err != nil {
fmt.Println("Load x509 key pair err:", err)
return
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
Certificates: []tls.Certificate{cliCrt},
},
}
client := &http.Client{Transport: tr}
resp, err := client.Get(reqUrl)
if err != nil {
fmt.Println("Get error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}