MDGSF Software Engineer

[GO] 使用 ssl 实现双向验证

2018-06-01
GO

https://github.com/MDGSF/GoPractice/tree/master/HTTPSDemo

server.go

package main

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

type myHandler struct {
}

func (h *myHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    w.Write([]byte("https demo server."))
}

var CAPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/ca.cer"
var ServerCertPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/server.cer"
var ServerKeyPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/server-key-out.pem"

func main() {
    rootPEM, err := ioutil.ReadFile(CAPath)
    if err != nil {
        log.Fatal("read ca.cer failed, err = %v", err)
    }

    roots := x509.NewCertPool()
    ok := roots.AppendCertsFromPEM(rootPEM)
    if !ok {
        log.Fatal("roots append failed")
    }

    tlsConfig := &tls.Config{}
    tlsConfig.ClientCAs = roots
    tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert

    s := &http.Server{}
    s.Addr = "localhost:10000"
    s.Handler = &myHandler{}
    s.TLSConfig = tlsConfig

    err = s.ListenAndServeTLS(ServerCertPath, ServerKeyPath)
    if err != nil {
        log.Fatalf("ListenAndServeTLS err = %v", err)
    }
}

client.go

package main

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

var CAPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/ca.cer"
var ClientCertPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/client.cer"
var ClientKeyPath = "/usr/local/gopath/src/github.com/MDGSF/GoPractice/HTTPSDemo/client-key-out.pem"

func main() {
    rootPEM, err := ioutil.ReadFile(CAPath)
    if err != nil {
        log.Fatal("read ca.cer failed, err = %v", err)
    }

    roots := x509.NewCertPool()
    ok := roots.AppendCertsFromPEM(rootPEM)
    if !ok {
        log.Fatal("roots append failed")
    }

    tlsConfig := &tls.Config{}
    //tlsConfig.ServerName = "localhost"
    tlsConfig.RootCAs = roots
    tlsConfig.Certificates = make([]tls.Certificate, 1)
    tlsConfig.Certificates[0], err = tls.LoadX509KeyPair(ClientCertPath, ClientKeyPath)
    if err != nil {
        log.Fatal("load x509 failed, err = %v", err)
    }

    tr := &http.Transport{}
    tr.TLSClientConfig = tlsConfig

    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://localhost:10000")
    if err != nil {
        log.Fatal("client get failed, err = %v", err)
    }

    content, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(strings.TrimSpace(string(content)))
}

weixingongzhonghao

Comments

Content