【问题标题】:Separate the below code in server.go and client.go将 server.go 和 client.go 中的以下代码分开
【发布时间】:2021-02-05 01:50:35
【问题描述】:

我在网上找到了这个代码,它动态生成 TLS 证书和密钥并注册它,当我运行它时,我也能够成功连接。

package main
 
import (
    "bytes"
    "crypto/rand"
    "crypto/rsa"
    "crypto/tls"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "math/big"
    "net"
    "net/http"
    "net/http/httptest"
    "strings"
    "time"
)
 
func main() {
    // get our ca and server certificate
    serverTLSConf, clientTLSConf, err := certsetup()
    if err != nil {
        panic(err)
    }
 
    // set up the httptest.Server using our certificate signed by our CA
    server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "success!")
    }))
    server.TLS = serverTLSConf
    server.StartTLS()
    defer server.Close()
 
    // communicate with the server using an http.Client configured to trust our CA
    transport := &http.Transport{
        TLSClientConfig: clientTLSConf,
    }
    http := http.Client{
        Transport: transport,
    }
    resp, err := http.Get(server.URL)
    if err != nil {
        panic(err)
    }
 
    // verify the response
    respBodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    body := strings.TrimSpace(string(respBodyBytes[:]))
    if body == "success!" {
        fmt.Println(body)
    } else {
        panic("not successful!")
    }
}
 
func certsetup() (serverTLSConf *tls.Config, clientTLSConf *tls.Config, err error) {
    // set up our CA certificate
    ca := &x509.Certificate{
        SerialNumber: big.NewInt(2019),
        Subject: pkix.Name{
            Organization:  []string{"Company, INC."},
            Country:       []string{"US"},
            Province:      []string{""},
            Locality:      []string{"San Francisco"},
            StreetAddress: []string{"Golden Gate Bridge"},
            PostalCode:    []string{"94016"},
        },
        NotBefore:             time.Now(),
        NotAfter:              time.Now().AddDate(10, 0, 0),
        IsCA:                  true,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
        KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
        BasicConstraintsValid: true,
    }
 
    // create our private and public key
    caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
        return nil, nil, err
    }
 
    // create the CA
    caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
    if err != nil {
        return nil, nil, err
    }
 
    // pem encode
    caPEM := new(bytes.Buffer)
    pem.Encode(caPEM, &pem.Block{
        Type:  "CERTIFICATE",
        Bytes: caBytes,
    })
 
    caPrivKeyPEM := new(bytes.Buffer)
    pem.Encode(caPrivKeyPEM, &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey),
    })
 
    // set up our server certificate
    cert := &x509.Certificate{
        SerialNumber: big.NewInt(2019),
        Subject: pkix.Name{
            Organization:  []string{"Company, INC."},
            Country:       []string{"US"},
            Province:      []string{""},
            Locality:      []string{"San Francisco"},
            StreetAddress: []string{"Golden Gate Bridge"},
            PostalCode:    []string{"94016"},
        },
        IPAddresses:  []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
        NotBefore:    time.Now(),
        NotAfter:     time.Now().AddDate(10, 0, 0),
        SubjectKeyId: []byte{1, 2, 3, 4, 6},
        ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
        KeyUsage:     x509.KeyUsageDigitalSignature,
    }
 
    certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
        return nil, nil, err
    }
 
    certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
    if err != nil {
        return nil, nil, err
    }
 
    certPEM := new(bytes.Buffer)
    pem.Encode(certPEM, &pem.Block{
        Type:  "CERTIFICATE",
        Bytes: certBytes,
    })
 
    certPrivKeyPEM := new(bytes.Buffer)
    pem.Encode(certPrivKeyPEM, &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
    })
 
    serverCert, err := tls.X509KeyPair(certPEM.Bytes(), certPrivKeyPEM.Bytes())
    if err != nil {
        return nil, nil, err
    }
 
    serverTLSConf = &tls.Config{
        Certificates: []tls.Certificate{serverCert},
    }
 
    certpool, _ := x509.SystemCertPool()
    if certpool == nil {
        certpool = x509.NewCertPool()
    }
    certpool.AppendCertsFromPEM(caPEM.Bytes())
    clientTLSConf = &tls.Config{
        InsecureSkipVerify: true,
    }
 
    return
}

现在我如何将它分成 2 个文件,如 server.go 和 client.go

这里它使用 httptest.NewUnstartedServer 而不是我想使用 ListenAndServeTLS 或一些类似的方法如何实现。

【问题讨论】:

  • 你试过什么?有一个明确的部分处理clientserver
  • 只是一些代码到 server.go 中,其余的到 client.go 中?
  • 嗨@shreyas。欢迎来到堆栈溢出。作为新的贡献者,我正在审查您的问题。我可以建议对您的问题进行一些更改吗? 1)你能解释一下为什么你被卡住了吗?是什么让你想问这个问题?是什么让你很难做到这一点? 2)解释为什么你试图将代码分成两个文件? 3) 你是 Golang 新手吗?对编程本身不熟悉?解释这些要点。 4)改写你的问题首先出现,即“现在我如何将它分成两个文件,如 server.go 和 client.go”。还要确保您的标题反映了实际问题。

标签: go ssl tls1.2


【解决方案1】:

要将您的代码重构为 server.go 和 client.go,您首先需要知道哪个部分在哪里,以及如何从您的主服务或其他服务访问它。在下面的文章中,您可以找到一个不错的重构代码的解释。 https://medium.com/@elliotchance/a-new-simpler-way-to-do-dependency-injection-in-go-9e191bef50d5

我假设您想使用 http 包 (https://golang.org/pkg/net/http/) 中的 ListenAndServeTLS 函数。

确保检查输入类型并将它们传递给函数。 func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error

如果您不熟悉接口和处理程序,请查看本文。 https://medium.com/@matryer/the-http-handler-wrapper-technique-in-golang-updated-bc7fbcffa702

【讨论】:

    猜你喜欢
    • 2015-03-29
    • 2018-11-19
    • 1970-01-01
    • 2014-10-16
    • 2019-04-25
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多