Using go to implement TLS servers and clients

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

The Transport Layer Security Protocol (TRANSPORT layer safety, abbreviation: TLS), and its predecessor, Secure Sockets Layer (secure Sockets layer, abbreviation: SSL) is a security protocol designed to provide security and data integrity assurance for Internet communications.

SSL contains the record layer and the transport layer, and the recording layer protocol determines the encapsulation format of the transport layer data. The Transport Layer Security protocol uses the authentication of the certificate, then uses the asymmetric encryption algorithm to authenticate the communication party, and then switches the symmetric key as the Session key. This meeting key is used to encrypt the data exchanged between the two sides of the communication, to ensure the confidentiality and reliability of communication between the two applications, so that communication between client and server application is not bugged by attackers.

This article does not provide a in-depth tutorial for TLS, but rather provides a simple example of two go application TLS to demonstrate the fast development of secure network transmission using the Go language.

TLS history

In the early 1994, Netscape company designed the 1.0 version of the SSL protocol (Secure Sockets Layer), but it was not released.
In November 1994, Netscape released SSL version 2.0 and soon found a serious loophole.
In November 1996, the SSL 3.0 version was introduced, and was widely used.
January 1999, the Internet Standardization organization ISOC replaced Netscape Company, released the SSL upgrade version of TLS version 1.0.
In April 2006 and August 2008, TLS was upgraded two times, respectively, for TLS version 1.1 and TLS 1.2. The latest change is the 2011 revision of the TLS 1.2.
TLS 1.3 is now being developed.

Certificate generation

First we create the private key and the certificate.

Server-side certificate generation

Server-side certificates are used to ensure that the servers are not counterfeit.

1. Generate server-side private key

1
OpenSSL Genrsa-out2048

2. Generate server-side certificates

1
OpenSSL req-new -x509-key server. Key 3650

Certificate Generation for clients

In addition to "server-side Certificates", "Client certificates" are also involved in some scenarios. The so-called "client certificate" is used to prove the identity of the client visitor.
For example, in some financial companies ' intranet, you must deploy a "client certificate" on your computer to open the pages of important servers.
I will demonstrate the use of the "client certificate" in the following example.

3. Generate the client's private key

1
OpenSSL Genrsa-out2048

4. Generate a certificate for the client

1
OpenSSL req-new -x509-key client. Key 3650

or use the following script:

12345678910
 #!/bin/bash  # call this script with an email Address (valid or not).  # like:  #./makecert.sh demo@random.com  mkdir certsrm certs/*echo   "Make server cert"  OpenSSL req-new-nodes-x509-out certs/server.pem-keyout certs/s Erver.key-days 3650 -subj  "/c=de/st=nrw/l=earth/o=random Company/ Ou=it/cn=www.random.com/emailaddress=$1  " echo   "Make client cert"  OpenSSL req-new-nodes-x509-out certs/client.pem-keyout certs/c Lient.key-days 3650 -subj  "/c=de/st=nrw/l=earth/o=random Company/ Ou=it/cn=www.random.com/emailaddress=$1  " 

Golang Example

The Go Package TLS section implements the TLS 1.2 functionality to meet our everyday applications. Package crypto/x509 provides the relevant operations for certificate management.

Use of server certificates

This section of the Code provides examples of server use certificates.

The following code is an example of a server:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
 PackageMainImport("Bufio""Crypto/tls""Log""NET")funcMain () {cert, err: = TLS. Loadx509keypair ("Server.pem","Server.key")ifErr! =Nil{log. PRINTLN (ERR)return}config: = &tls. Config{certificates: []tls. CERTIFICATE{CERT}}LN, err: = TLS. Listen ("TCP",": 443", config)ifErr! =Nil{log. PRINTLN (ERR)return}deferln. Close () for{conn, err: = ln. Accept ()ifErr! =Nil{log. PRINTLN (ERR)Continue}GoHANDLECONN (conn)}}funcHANDLECONN (Conn net. Conn) {deferConn. Close () r: = Bufio. Newreader (conn) for{msg, err: = R.readstring (' \ n ')ifErr! =Nil{log. PRINTLN (ERR)return}println(msg) n, err: = conn. Write ([]byte("world\n"))ifErr! =Nil{log. PRINTLN (n, err)return}}}

First get the certificate from the server private key and Pem file we created above cert , and generate a TLS. Config object. This object has more than one field to set, in this case we use its default value.
Then tls.Listen you start listening to the client connection and receive a net after accept. Conn, subsequent processing is the same as for normal TCP programs.

Then, let's look at how the client is implemented:

12345678910111213141516171819202122232425262728293031323334
 PackageMainImport("Crypto/tls""Log")funcMain () {conf: = &tls. Config{insecureskipverify:true,}conn, err: = TLS. Dial ("TCP","127.0.0.1:443", conf)ifErr! =Nil{log. PRINTLN (ERR)return}deferConn. Close () n, err: = conn. Write ([]byte("hello\n"))ifErr! =Nil{log. PRINTLN (n, err)return}buf: = Make([]byte, -) N, err = conn. Read (BUF)ifErr! =Nil{log. PRINTLN (n, err)return}println(string(Buf[:n])}

InsecureSkipVerifyUsed to control whether the client is a certificate and server hostname. If set to True, the certificate is not validated and the host name and server hostname are consistent.
Because the self-signed certificate is used in our example, it is set to true for testing purposes only.

As can be seen, the whole program is written and ordinary TCP programs are poorly written, but initially need to do some TLS configuration.

You can go run server.go and go run client.go test this example.

Use of client certificates

In some cases, two-way authentication is required, and the server needs to verify the authenticity of the client. In this case, we need a little extra configuration from the server and the client.

Server-side:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 66676869
 PackageMainImport("Bufio""Crypto/tls""crypto/x509""Io/ioutil""Log""NET")funcMain () {cert, err: = TLS. Loadx509keypair ("Server.pem","Server.key")ifErr! =Nil{log. PRINTLN (ERR)return}certbytes, err: = Ioutil. ReadFile ("Client.pem")ifErr! =Nil{Panic("Unable to read CERT.PEM")}clientcertpool: = X509. Newcertpool () OK: = Clientcertpool.appendcertsfrompem (certbytes)if!ok {Panic("Failed to parse root certificate")}config: = &tls. Config{certificates: []tls. Certificate{cert},clientauth:tls. REQUIREANDVERIFYCLIENTCERT,CLIENTCAS:CLIENTCERTPOOL,}LN, err: = TLS. Listen ("TCP",": 443", config)ifErr! =Nil{log. PRINTLN (ERR)return}deferln. Close () for{conn, err: = ln. Accept ()ifErr! =Nil{log. PRINTLN (ERR)Continue}GoHANDLECONN (conn)}}funcHANDLECONN (Conn net. Conn) {deferConn. Close () r: = Bufio. Newreader (conn) for{msg, err: = R.readstring (' \ n ')ifErr! =Nil{log. PRINTLN (ERR)return}println(msg) n, err: = conn. Write ([]byte("world\n"))ifErr! =Nil{log. PRINTLN (n, err)return}}}

Because the client needs to be validated, we need to configure the following two additional fields:

12
ClientAuth:   TLS. Requireandverifyclientcert,clientcas:    Clientcertpool,

The client then configures this as well clientCertPool :

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
 PackageMainImport("Crypto/tls""crypto/x509""Io/ioutil""Log")funcMain () {cert, err: = TLS. Loadx509keypair ("Client.pem","Client.key")ifErr! =Nil{log. PRINTLN (ERR)return}certbytes, err: = Ioutil. ReadFile ("Client.pem")ifErr! =Nil{Panic("Unable to read CERT.PEM")}clientcertpool: = X509. Newcertpool () OK: = Clientcertpool.appendcertsfrompem (certbytes)if!ok {Panic("Failed to parse root certificate")}conf: = &tls. Config{rootcas:clientcertpool,certificates: []tls. Certificate{cert},insecureskipverify:true,}conn, err: = TLS. Dial ("TCP","127.0.0.1:443", conf)ifErr! =Nil{log. PRINTLN (ERR)return}deferConn. Close () n, err: = conn. Write ([]byte("hello\n"))ifErr! =Nil{log. PRINTLN (n, err)return}buf: = Make([]byte, -) N, err = conn. Read (BUF)ifErr! =Nil{log. PRINTLN (n, err)return}println(string(Buf[:n])}

Run both code go run server2.go and go run client2.go you can see that both can communicate properly, if using the previous client go run client.go , cannot communicate normally, because the front client does not provide a client certificate.

Reference documentation and code

    1. Https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0
    2. http://drops.wooyun.org/tips/6002
    3. http://www.levigross.com/2015/11/21/mutual-tls-authentication-in-go/
    4. Https://github.com/nareix/blog/blob/master/posts/golang-tls-guide.md
    5. Http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
    6. https://gist.github.com/spikebike/2232102
    7. Https://github.com/nareix/tls-example
    8. http://seanlook.com/2015/01/07/tls-ssl/
    9. https://golang.org/pkg/crypto/tls/
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.