golang https server(二)

之前的blog介绍了https的单向认证流程,这里再介绍一下双向认证的过程。人多人没有理解双向认证的过程,这里先介绍一下认证流程
这里写图片描述
这里的ca证书其实是可以不一样的,这是很多人的误区,服务端证书用服务端的ca签名过后,客户端应该用服务的ca去认证,而不是客户端自己的ca,如果ca是相同的当然无所谓,下面是生成证书的过程

  • 服务端:
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=ca.com" -days 5000 -out ca.crt

openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=server" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
  • 客户端:
openssl genrsa -out clinet-ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=ca.com" -days 5000 -out client-ca.crt

openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=client" -out client.csr
openssl x509 -req -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client.crt -days 5000

这样证书就生成了,下面看golang的测试代码:
服务端:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "net/http"
)

type myhandler struct {
}

func (h *myhandler) ServeHTTP(w http.ResponseWriter,
r *http.Request) {
    fmt.Fprintf(w,
        "Hi, This is an example of http service in golang!\n")
}

func main() {
    pool := x509.NewCertPool()
    caCertPath := "client-ca.crt"

    caCrt, err := ioutil.ReadFile(caCertPath)
    if err != nil {
        fmt.Println("ReadFile err:", err)
        return
    }
    pool.AppendCertsFromPEM(caCrt)

    s := &http.Server{
        Addr:    ":8081",
        Handler: &myhandler{},
        TLSConfig: &tls.Config{
            ClientCAs:  pool,
            ClientAuth: tls.RequireAndVerifyClientCert,
        },
    }

    err = s.ListenAndServeTLS("server.crt", "server.key")
    if err != nil {
        fmt.Println("ListenAndServeTLS err:", err)
    }
}

注意,这个里面使用的是客户端的ca证书
同理客户端:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    pool := x509.NewCertPool()
    caCertPath := "ca.crt"

    caCrt, err := ioutil.ReadFile(caCertPath)
    if err != nil {
        fmt.Println("ReadFile err:", err)
        return
    }
    pool.AppendCertsFromPEM(caCrt)

    cliCrt, err := tls.LoadX509KeyPair("client.crt", "client.key")
    if err != nil {
        fmt.Println("Loadx509keypair err:", err)
        return
    }

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            RootCAs:      pool,
            Certificates: []tls.Certificate{cliCrt},
        },
    }
    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://server:8081")
    if err != nil {
        fmt.Println("Get error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

使用的是服务的ca这样就完成了双向认证的过程

猜你喜欢

转载自blog.csdn.net/u010278923/article/details/79204444
今日推荐