zoukankan      html  css  js  c++  java
  • 创建并使用https证书

    前言

    https要比http更安全些,因此可以配置Nginx服务器使用证书,客户端就会去第三方平台校验证书。
    但是我们自己的服务器和客户端只是想要加个密而已,也没必要跑去第三方平台校验证书,省钱方便。
    因此研究了一下生成证书和使用证书的笔记。

    产生证书

    网上很多都是用openssl命令行去产生,有点麻烦,主要是不想记一堆命令,因此找到一个非常简单的项目。
    项目地址:https://github.com/michaelklishin/tls-gen,需要环境有python3、openssl、make这三个工具。
    使用方法cd tls-gen/basic & make CN=www.janbar.com,这样客户端必须用该域名进行访问,并且要带上对应证书。
    最终产生如下三个文件,testca/cacert.pem是客户端使用,server/cert.pem,server/key.pem是服务器使用。

    testca/
      cacert.pem
    
    server/
      cert.pem
      key.pem
    

    记得在c:WindowsSystem32driversetchosts增加127.0.0.1 www.janbar.com,准备证书源码文件cert.go,内容如下:

    
    var (
        certPEMBlock = []byte(`-----BEGIN CERTIFICATE-----
    MIIDfjCCAmagAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMSAwHgYDVQQDDBdUTFNH
    ZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDAeFw0yMTAxMjExMDEx
    MjJaFw0zMTAxMTkxMDExMjJaMCoxFzAVBgNVBAMMDnd3dy5qYW5iYXIuY29tMQ8w
    DQYDVQQKDAZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDj
    pGglwTB/B1N07ZhwaP3erxDZDYhtDqir7fiuZQxgmWzQ5UeU7gp5ntu8bLXpFmVS
    s7si0WyOKbGoPi8Q/cvkZix3zkClAvS7vM2zW+0qa3Fp4dYRg42cjYAgenfpC0M5
    fKHhnBKjzWFOiTOyJIPcNpvhAcV9dvQIdgX64g/+M2J3pMK2+tU5Z49Nc1KqyUS/
    /zFo4C+HAk7Wbkc3Kgx8t4OZo0ddTdmLsPfRIU3hxqehRxhk7OccHBBb6JOVSF21
    3h6kWwauN9djiOixpsS3jr1SVEGrhZk6zaOtZ+MSOg410pr3u79kdIuCYGNhvdDW
    soyNBNCFGOP/kj7dO5p/AgMBAAGjgacwgaQwCQYDVR0TBAIwADALBgNVHQ8EBAMC
    BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwNQYDVR0RBC4wLIIOd3d3LmphbmJhci5j
    b22CD0RFU0tUT1AtQ1YxUUhPRIIJbG9jYWxob3N0MB0GA1UdDgQWBBSUjXz9K9NO
    tJJs+YXHVBUBG5RPEzAfBgNVHSMEGDAWgBRFxl2tSPMYhPZ+Pf6O1HiZ65yJzzAN
    BgkqhkiG9w0BAQsFAAOCAQEALxVtveN3LI1vi4uiaId6O87OjirugSD1xSkD7MFj
    aBb2u0+a/ziiNXeLCtxNxSb7HTknd/6SuTdgHzq1sCczk0BcV3FfEjNw3Y4sz9JO
    0CBFnpgIvqFoA+rJEIiUwhyOkCh/aIVT8VMGm3gAHAeMhrYd4iF590+P1vgXTrvr
    6T3FKojng3IgXxYzVUcia/UNEfY8U6f6yThC22kcThK/OeywpLB+NCm9/wt7sQUZ
    T8BEfhz0AKHFIih8wq5DD87Vc6fHkUBX6NBKmstm5X5smQTjJGd985fx1Rdka5ro
    o0IH6DYd8PjN0asvEb1RG5viSpcpXc5IFh7mNzmxaA7Ygw==
    -----END CERTIFICATE-----`)
        keyPEMBlock = []byte(`-----BEGIN PRIVATE KEY-----
    MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjpGglwTB/B1N0
    7ZhwaP3erxDZDYhtDqir7fiuZQxgmWzQ5UeU7gp5ntu8bLXpFmVSs7si0WyOKbGo
    Pi8Q/cvkZix3zkClAvS7vM2zW+0qa3Fp4dYRg42cjYAgenfpC0M5fKHhnBKjzWFO
    iTOyJIPcNpvhAcV9dvQIdgX64g/+M2J3pMK2+tU5Z49Nc1KqyUS//zFo4C+HAk7W
    bkc3Kgx8t4OZo0ddTdmLsPfRIU3hxqehRxhk7OccHBBb6JOVSF213h6kWwauN9dj
    iOixpsS3jr1SVEGrhZk6zaOtZ+MSOg410pr3u79kdIuCYGNhvdDWsoyNBNCFGOP/
    kj7dO5p/AgMBAAECggEAIG96j3aZbGAk2hJImCu9kI8tPWAaQj/GdMjxmBe5zcHO
    qW0h5+yK/Y1PDegHe3C/eys0zN8+MntqXuiNWERxWtfcGi3/NAPZzy41uQquHk80
    17tf/xrZgKcAzJ/mmgQKzhQeFMFiPoizBrex7/4X87asO0E/XIMoflQiwf6X/MYc
    w/2ExWGoSxucsZs1J7HuBWp10G26t7yZEEFy+IjS8aleNnBm0vBgSZ2R/cqIpqTD
    hvfnM/Xv8ERVMlj+pzac+qzAyRJHgEkYdOzwy9+7v9bT3fv99I+jHJjo5qMu4/vM
    s2QMypO2ams4ClbB6bgcq1Bt8/WATXoS4hbyCNDNYQKBgQDzBnJKQ3Iqc7rqYHDY
    romxqwyeHsi5sCXCsA806drQBIX+n3MhJ5UcveDNW6QtNPX8/v8JWLU+yR64zatf
    Qz5YFBLcF2NYvkO3z5vrvCmRYZaAbmMv1I+RKTWL2UDi1JBTteTG5g9BLIPMGIuz
    WNVnrAG61IsHLnBzUvMuLxJn6QKBgQDvy7aW22yocsZBUlZ0bDxY7OieEQbCuafx
    ncbGlSRfqCkwU1MKifZHFbLlxlklr+bQJRDlN2RYtLBSKeU65PK2zm7G6hgRcBMG
    52SiW59QoGmiP5DmZj4ILAV9/SmlTRsnB6q2OXdkAZ06vNI2oPMznSUiFyB2MJiH
    lrG0MGnWJwKBgQDt5oKdNjcdXZs9ctklFH8QYIyCgUonlErysdzBBKhB+BufrUFL
    1G7A6xOUlEA8TNr9JjZNVPxgEQu1BwjawX3XRRdNQsvrBJ5P4rkU5GagvbJR2T3Z
    hbBg/sE/PJarNkBu4eGp325Rc501f1XKZIzL5vLujL/ocMp96lbKACR5eQKBgDTF
    2WYz3iLoN3dyvnIay+EqKjt3Ncyu/SXweimD8yBWKtJm1BSyrg+Q1/E3iLEBmENg
    lOpNGXloMpGyhK9EaaIPplOCe0+DIbzYOc59aX9d/kFlyebaw3Ya8g57I6osYPhi
    +I/n772DmW2u1niNTVijkeOBwXQhV8AnSu6D5RbrAoGBAOycwo6VQGUNkwQW6e02
    32TdC9C66Ky8tB/SWusu6fGD6hpHBA15T/saOuZ6WE0ir7VGyAr1P04mYebcZ31P
    B14WxQ1BhT6MGdd6DK+kG+gIfT38sSwy/sHIpbM+KcijmX2jJ1qf1O8TJHlvXMdx
    fuPIaJgJmNZtnQtAo2f+XVWp
    -----END PRIVATE KEY-----`)
        rootPEM = []byte(`-----BEGIN CERTIFICATE-----
    MIIDUDCCAjigAwIBAgIUI8rwLlo1JMFnSeuNOdR7qf1vkU4wDQYJKoZIhvcNAQEL
    BQAwMTEgMB4GA1UEAwwXVExTR2VuU2VsZlNpZ25lZHRSb290Q0ExDTALBgNVBAcM
    BCQkJCQwHhcNMjEwMTIxMTAxMTIyWhcNMzEwMTE5MTAxMTIyWjAxMSAwHgYDVQQD
    DBdUTFNHZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDCCASIwDQYJ
    KoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6NWvQP5lDgIDh5IC/BDHm1egEP3BG1
    Mqu0rO0505Vp5Y1/oc3OGqi3cJLcJ0JOjq4Y6pjTmqlf0zLG1LgRw96bJid0LI2O
    iCDHCkdu3efU3aWxXgGxRBLPe8g7JHUSoIGsERrjqxsplQ38z6n+Yzbndjixz11r
    MCeQXS+FZeHFdkqEiy7DDrDa1OxthH8lFjPqcxBC5Dz4OO7eNhwLtru9sMSYYvOL
    jO6TmpHsd6OHUDVFFfaXSxHGeRFKDm9cYqKmO4oexm4QFAtoDaWCDXcAnS8hi7ze
    wAGhVPTRZp/lXuCqwsAAjU40vb8Pqq5zuY05eCYINwPYY5S1OMNTfJMCAwEAAaNg
    MF4wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBRFxl2tSPMYhPZ+Pf6O1HiZ65yJzzAf
    BgNVHSMEGDAWgBRFxl2tSPMYhPZ+Pf6O1HiZ65yJzzAPBgNVHRMBAf8EBTADAQH/
    MA0GCSqGSIb3DQEBCwUAA4IBAQA03g3/AC3ylUjATzhxyglarRNrneZKM96KFm3c
    z99HzxBxX71hKBF6kV6GKdKQkl4Ocx6HLiHiIWviTFr0qNVNcafrdDwWa9dRg5da
    xKOOE9XoLYHWDmDaKgAIz4x5tDUDhAT4u7hkHQACz4TMlQG6L2uXPI0IiTv5185w
    vgNNpx2V3d9rlvq6AOWjhSrZ9rfuSnt3UbRjKmbZAGcaFb3Gqr7MdIZuYOB9CN7H
    o0wKNxKk00o7jav298tHinDdKvwYdAf8IgkEaHgBeFsPfNy8VGe4XWNdVT7HkzpO
    PHM7SBK+cEpKnylKkEdKb9ubSCe8NA4RpuKbeo36IS6Bcfmr
    -----END CERTIFICATE-----`)
    )
    

    测试https服务器

    测试代码文件test_https.go如下:

    package main
    
    import (
        "crypto/tls"
        "crypto/x509"
        "io"
        "net/http"
        "os"
        "time"
    )
    
    func main() {
        http.Handle("/", http.FileServer(http.Dir(".")))
    
        go func() {
            cf, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
            if err != nil {
                panic(err)
            }
            err = (&http.Server{TLSConfig: &tls.Config{
                Certificates: []tls.Certificate{cf},
            }}).ListenAndServeTLS("", "")
            if err != nil {
                panic(err)
            }
        }()
        time.Sleep(time.Second)
        // 上面是http服务器的运行
    
        // 下面是http客服端访问
        roots := x509.NewCertPool()
        ok := roots.AppendCertsFromPEM(rootPEM)
        if !ok {
            panic("failed to parse root certificate")
        }
    
        client := &http.Client{Transport: &http.Transport{
            TLSClientConfig: &tls.Config{RootCAs: roots},
        }}
    
        req, err := http.NewRequest(http.MethodGet, "https://www.janbar.com", nil)
        if err != nil {
            panic(err)
        }
        resp, err := client.Do(req)
        if err != nil {
            panic(err)
        }
        io.Copy(os.Stdout, resp.Body)
        resp.Body.Close()
    }
    

    执行go run test_https.go cert.go效果如下,显示了运行目录下的文件列表:

    <pre>
    <a href="test.exe">test.exe</a>
    <a href="test.go">test.go</a>
    </pre>
    

    用tls加密tcp连接

    测试代码test_tcp.go文件,源码如下:

    package main
    
    import (
        "crypto/tls"
        "crypto/x509"
        "fmt"
        "net"
        "time"
    )
    
    func main() {
        addr := "www.janbar.com:8080"
        go func() {
            err := tcpServer(addr)
            if err != nil {
                panic(err)
            }
        }()
        time.Sleep(time.Second)
        err := tcpClient(addr)
        if err != nil {
            panic(err)
        }
    }
    
    func tcpServer(addr string) error {
        cf, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
        if err != nil {
            return err
        }
        s, err := tls.Listen("tcp", addr, &tls.Config{Certificates: []tls.Certificate{cf}})
        if err != nil {
            return err
        }
        defer s.Close()
    
        client := func(c net.Conn) error {
            tNow := time.Now().String()
            buf := make([]byte, len(tNow))
            n, err := c.Read(buf)
            if err != nil {
                return err
            }
            fmt.Printf("server [%s]
    ", buf[:n])
            _, err = c.Write([]byte(tNow))
            return err
        }
    
        for {
            l, err := s.Accept()
            if err != nil {
                return err
            }
            go func(c net.Conn) {
                defer c.Close()
                if err := client(c); err != nil {
                    fmt.Println(err)
                }
            }(l)
        }
    }
    
    func tcpClient(addr string) error {
        roots := x509.NewCertPool()
        ok := roots.AppendCertsFromPEM(rootPEM)
        if !ok {
            panic("failed to parse root certificate")
        }
        c, err := tls.Dial("tcp", addr, &tls.Config{RootCAs: roots})
        if err != nil {
            return err
        }
        defer c.Close()
    
        tNow := time.Now().String()
        c.Write([]byte(tNow))
        buf := make([]byte, len(tNow))
        n, err := c.Read(buf)
        if err != nil {
            return err
        }
        fmt.Printf("client [%s]
    ", buf[:n])
        return nil
    }
    

    执行go run test_tcp.go cert.go效果如下:

    server [2021-01-21 21:09:51.7942154 +0800 CST m=+1.011929701]
    client [2021-01-21 21:09:51.7852425 +0800 CST m=+1.002956801]
    

    总结

    以前使用的tcp连接没有任何加密,现在想想还是不安全。用上证书,起码会校验访问域名和证书等信息,多少会安全一些。
    以上都是用来测试等等,如果需要正式使用证书,还是去各大网站花钱申请吧。我一直用万网的免费证书,但是有效期只有一年额。

  • 相关阅读:
    linux软件安装方式
    docker 安装 jenkins touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
    [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    Linux 常用命令 服务器间scp 用户 export 创建文件、软连接
    redis 安装 集群 主从 哨兵 docker
    WPF密码框中禁止复制、粘贴
    Application 统计在线人数
    【转义字符】HTML 字符实体&lt; &gt: &amp;等
    SQL语句统计每天的数据
    正则表达式计算代码数
  • 原文地址:https://www.cnblogs.com/janbar/p/14310465.html
Copyright © 2011-2022 走看看