Go code get through HTTPS

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

TL;DR Manually create a CA certificate chain, handwritten code to get through HTTPS at both ends

HTTPS has recently been an important topic, but also a somewhat difficult topic to understand. So there are a lot of https/tls/ssl tutorials on the internet. The principle of these, do not explain here, interested can search by themselves.

This article describes a process of creating a certificate yourself and writing the Go code to implement Client/server on both ends. Help understand from a practical point of view.

Building a CA certificate chain

We will first create the certificate used by Client/server. There are many ways to create a certificate: There is no fear of trouble, directly through OpenSSL
Created by Cfssl. Here's what I think is the simplest one:tls-gen

tls-genis a very easy-to-use tool written in Python. It defines three types of profiles. Here we choose the simplest one: a root certificate and a set of certificates, private key pairs.

Execute the command inside the shell:

    1. git clone https://github.com/michaelklishin/tls-gen
    2. cd tls-gen/basic
    3. make CN=www.mytestdomain.io

In this way, we create a set of certificates for the domain name www.mytestdomain.io . Looking at the contents of the current path, we will find two new directories: testca and server . The former stores the root certificate (root CA) that was just created, which stores the certificate and private key that our service program will use.

testca/  cacert.pemserver/  cert.pem  key.pem

Writing Services

Then start writing the code. Go to TLS support is relatively complete, but also relatively simple. The following is the server-side code (server.go) :

func HelloServer(w http.ResponseWriter, req *http.Request) {    w.Header().Set("Content-Type", "text/plain")    w.Write([]byte("This is an example server.\n"))}func main() {    http.HandleFunc("/hello", HelloServer)    err := http.ListenAndServeTLS(":1443", "server/cert.pem", "server/key.pem", nil)    if err != nil {        log.Fatal("ListenAndServe: ", err)    }}

You can see that we have created an HTTP service that listens on port 1443 and processes only one path /hello . The following function is then called to listen on port 1443. Note that we give the certificate and private key of the service we created earlier-this ensures that HTTP is transmitted in an encrypted manner.

ListenAndServeTLS(addr, certFile, keyFile string, handler Handler)

To run the service program:

go run server.go

Access to HTTPS services

Suppose our service program is running on-premises. Let's change it first /etc/hosts to configure the domain name resolution:

# echo 127.0.0.1 www.mytestdomain.io >> /etc/hosts

We use the following code (client.go) to access the service:

func main() {    client := &http.Client{}    resp, err := client.Get("https://www.mytestdomain.io:1443/hello")    if err != nil {        panic("failed to connect: " + err.Error())    }    content, _ := ioutil.ReadAll(resp.Body)    s := strings.TrimSpace(string(content))    fmt.Println(s)}

go run client.goto run, you can only get such an error:

panic: failed to connect: Get https://www.mytestdomain.io:1443/hello: x509: certificate signed by unknown authorit

This is because the system does not know how to handle this self signed certificate.

The methods for adding root certificates to each OS are different. For Linux systems (in Ubuntu, for example), put the certificate file in the appropriate directory:

# sudo cp testca/cacert.pem /etc/ssl/certs

If it's MacOS, you can use the command:

# sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain  testca/cacert.pem

The above method will take us to manually create the root CA
Added to the list known to the system. In this way, all the root CAs
The certificates created can be certified.

Now we run the process again and we will be able to get a response from the server:

This is an example server.

Another way to access

If just a normal user, no Root/sudo permissions, can not do the above operation? There is another way of doing this: place the root CA in the code.

client.goadd a few lines of code to the above:

func main() {    roots := x509.NewCertPool()    ok := roots.AppendCertsFromPEM([]byte(rootPEM))    if !ok {        panic("failed to parse root certificate")    }    tr := &http.Transport{        TLSClientConfig: &tls.Config{RootCAs: roots},    }    client := &http.Client{Transport: tr}    // ...

The content of which rootPEM is testca/cacert.pem

var Rootpem = '-----BEGIN CERTIFICATE-----MIIDAJCCAEQGAWIBAGIJAL2FAQA73YLVMA0GCSQGSIB3DQEBCWUAMDEXIDAEBGNVBAMMF1RMU0DLBLNLBGZTAWDUZWR0UM9VDENBMQ0WC Wydvqqhdaqkjcqkmb4xdte4mdiwnta5mzc0nvoxdti4mdiwmza5mzc0nvowmtegmb4ga1ueawwxvextr2vuu2vszlnpz25lzhrsb290q0exdtalbgnvbacmbc Qkjcqwggeima0gcsqgsib3dqebaquaa4ibdwawggekaoibaqc9eo6tam4xfdubk9fastag29teyektt8wejvkgb50xmfxo2pd0stsxhkrspxbyck0fwkibstl R97w7dsqa64z3u2v2borogfzoee4jh2sydygaqqnaqezgx8vznqvryzebifrpebr4wvd5gtxye+ mnskhpigsg0qg0saisfml05dsjhoe9t9kly9fh6yed88++oyjzzrgkof2thpqlxjjf3iwcdlkwz9z/kjmpk/ rr0sehtanf7boggs3oofmx4dvmfjxorivuc9jcj0z4ox3ld81xxyd4fjkpkvdkdhykqcugfgerqdberdm+ Ma38yookhzh0kll2ethnxjxm0r1vagmbaagjhtabmawga1udewqfmambaf8wcwydvr0pbaqdagegma0gcsqgsib3dqebcwuaa4ibaqbeqp0on1a /pckfztfkuzdw+9paue8dl6ij3++dt6aqw5qyfloefqwombokgchgqdxhkakyaa0dfge5jntmh0yyyznr4kfs+acy6p+ 2pfgrgvbqadhr6uagobaxdw7dlllqijj8nrina/ftdyxmxbjbfrcj2cgiyvpvabrosz5l/ydadvm76v8uuk8hmmy5zrqj+gwt/ Jdkywfrp0b6k3fbxvm7+nhqaidymjlioadywfppglgj3xhxs5newjyudlayisne+pkmerSEDRPTYDE+LJZL77HVVFZD9OPHXBDKAEVU/NADWHG/G5HDVDNBG/FZ6UEEVF34XUZEJM3LRDJM-----END CERTIFICATE-----' 

In other words, we have created a new HTTP transport with the content of the prepared root CA.

Run a bit go run client.go . Success!

This is an example server.

Summarize

A common root CA is required in a pair of HTTPs client/server programs. The root CA is required on the server side
Creates a ca/private key pair.

This is achieved using the Go language, and the other language processes are similar.

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.