Certificate issuance and two-way authentication using Golang

Source: Internet
Author: User
Tags openssl rsa readfile
This is a creation in Article, where the information may have evolved or changed.


Objective



A digital certificate is a file that is digitally signed by the Certificate Authority center that contains public key owner information and a public key. Certificate issuance involves knowledge of asymmetric cryptography, which describes the use of the X509 standard library in Golang for certificate self-issuance, and how to use Golang for two-way authentication after a certificate is issued.



Self-issued certificate



Generate Root Certificate



The root certificate is the certificate issued by the CA Certification Center to itself and is the starting point of the chain of trust. Here we do it ourselves. The CA uses the OpenSSL command to generate the root certificate.



First generate the private key


openssl genrsa -out key.pem 2048
Then extract the public key based on the private key

openssl rsa -in key.pem -pubout -out key.pub
Start to generate self-signed certificate in X509 format, you will be asked to enter the various information of the distinguished name DN (country, city, organization, name, email, etc.).

penssl req -x509 -new -days 365 -key rsakey.pem -out cert.crt
At this point, the root certificate is made.Let's start using golang to issue the next-level certificate based on the root certificate.

Self-signed certificate using golang
Regarding the process of self-signed certificate, here is a brief introduction. Golang's x509 standard library has a Certificate structure. This structure is the corresponding entity after the certificate is parsed. The new certificate needs to generate a key pair first, and then use the private key of the root certificate. For signature, certificate, private key and public key, here is the pem encoding method.

First read the certificate and private key of the root certificate

    // Parse the root certificate
    caFile, err: = ioutil.ReadFile (rootCa)
    if err! = nil {
        return
    }
    caBlock, _: = pem.Decode (caFile)

    cert, err: = x509.ParseCertificate (caBlock.Bytes)
    if err! = nil {
        return
    }
    // Parse the private key
    keyFile, err: = ioutil.ReadFile (rootKey)
    if err! = nil {
        return
    }
    keyBlock, _: = pem.Decode (keyFile)
    praKey, err: = x509.ParsePKCS1PrivateKey (keyBlock.Bytes)
    if err! = nil {
        return
    }
Then you need to generate a template for the new certificate.The fields inside are filled in according to your needs.

cer: = & x509.Certificate {
        SerialNumber: big.NewInt (rd.Int63 ()), // certificate serial number
        Subject: pkix.Name {
            Country: [] string {"CN"},
            Organization: [] string {"Easy"},
            OrganizationalUnit: [] string {"Easy"},
            Province: [] string {"ShenZhen"},
            CommonName: equi.Code,
            Locality: [] string {"ShenZhen"},
        },
        NotBefore: time.Now (), // Certificate validity start time
        NotAfter: time.Now (). AddDate (1, 0, 0), // end time of certificate validity period
        BasicConstraintsValid: true, // Basic validity constraints
        IsCA: false, // Whether it is a root certificate
        ExtKeyUsage: [] x509.ExtKeyUsage {x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, // certificate usage (client authentication, data encryption)
        KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment,
        EmailAddresses: [] string {"test@test.com"},
        IPAddresses: [] net.IP {net.ParseIP ("192.168.1.59")},
    }
When this information is obtained, a certificate can be issued, and key and ca are the issued certificate and private key.

    // Generate a public key private key pair
    priKey, err: = rsa.GenerateKey (rand.Reader, 2048)
    if err! = nil {
        return
    }
    ca, err = x509.CreateCertificate (rand.Reader, equiCer, rootCa, & priKey.PublicKey, rootKey)
    if err! = nil {
        return
    }

    // Encode the certificate file and private key file
    caPem: = & pem.Block {
        Type: "CERTIFICATE",
        Bytes: ca,
    }
    ca = pem.EncodeToMemory (caPem)

    buf: = x509.MarshalPKCS1PrivateKey (priKey)
    keyPem: = & pem.Block {
        Type: "PRIVATE KEY",
        Bytes: buf,
    }
    key = pem.EncodeToMemory (keyPem)
Two-way authentication using golang
Client

    // Load the client certificate
    // Loaded here is issued by the server
    cert, err: = tls.LoadX509KeyPair ("client_cert.pem", "client_key.pem")
    if err! = nil {
        log.Fatalln (err)
    }

    config: = & tls.Config {
        // The server certificate is not verified here, it is issued by yourself
        InsecureSkipVerify: true,
        Certificates: [] tls.Certificate {cert},
    }

    raddr, err: = net.ResolveTCPAddr ("tcp", "192.168.1.59:6001")
    if err! = nil {
        log.Fatalln (err)
    }
    conn, err: = net.DialTCP ("tcp", nil, raddr)
    if err! = nil {
        log.Fatalln (err)
    }

    tlsConn: = tls.Client (conn, config)
tlsConn is the same as net.Conn. When Wirte is called, a handshake is performed.If the server certificate does not meet the requirements, an error is returned.

Server

    // The root certificate is read here
    buf, err: = ioutil.ReadFile (d.conf.Tls.CA)
    if err! = nil {
        return
    }

    pool: = x509.NewCertPool ()
    pool.AppendCertsFromPEM (buf)

    // Load server certificate
    cert, err: = tls.LoadX509KeyPair (d.conf.Tls.Cert, d.conf.Tls.Key)
    if err! = nil {
        return
    }

    tlsConfig: = & tls.Config
        Certificates: [] tls.Certificate {cert},
        ClientAuth: tls.RequireAndVerifyClientCert,
        ClientCAs: pool,
    }
    // After accept to conn
    tlsConn: = tls.Server (conn, tlsConfig)
This tlsConn is the same as the client, and you can also manually call Handshake for handshake.

Conclusion
Here is only a brief introduction, and the knowledge about certificates is not limited to this. For example, the x509 standard library can also generate certificate issue requests, parse certificate revocation lists, and so on. You need to practice more to understand the certificate.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.