本篇文章介绍一下使用TLS/SSL创建安全的TCP通信,首先我们要准备一个数字证书和一个密钥关于如何产生密钥,请看下面文章:
Author: 岳东卫
Email: usher.yue@gmail.com
通过Openssl创建数字证书和密钥
TLS服务器端代码
- package main
-
- import (
- "crypto/rand"
- "crypto/tls"
- "fmt"
- "log"
- "net"
- "time"
- )
-
- func HandleClientConnect(conn net.Conn) {
- defer conn.Close()
- fmt.Println("Receive Connect Request From ",conn.RemoteAddr().String())
- buffer := make([]byte, 1024)
- for {
- len,err := conn.Read(buffer)
- if err != nil {
- log.Println(err.Error())
- break
- }
- fmt.Printf("Receive Data: %s\n",string(buffer[:len]))
- //发送给客户端
- _,err = conn.Write([]byte("服务器收到数据:" + string(buffer[:len])))
- if err != nil {
- break
- }
- }
- fmt.Println("Client " + conn.RemoteAddr().String() + " Connection Closed.....")
- }
-
- func main() {
- crt,err := tls.LoadX509KeyPair("server.crt","server.key")
- if err != nil {
- log.Fatalln(err.Error())
- }
- tlsConfig := &tls.Config{}
- tlsConfig.Certificates = []tls.Certificate{crt}
- // Time returns the current time as the number of seconds since the epoch.
- // If Time is nil,TLS uses time.Now.
- tlsConfig.Time = time.Now
- // Rand provides the source of entropy for nonces and RSA blinding.
- // If Rand is nil,TLS uses the cryptographic random reader in package
- // crypto/rand.
- // The Reader must be safe for use by multiple goroutines.
- tlsConfig.Rand = rand.Reader
- l,err := tls.Listen("tcp",":8888",tlsConfig)
- if err != nil {
- log.Fatalln(err.Error())
- }
- for {
- conn,err := l.Accept()
- if err != nil {
- fmt.Println(err.Error())
- continue
- } else {
- go HandleClientConnect(conn)
- }
- }
-
- }
TLS客户端代码
- package main
-
- import (
- "crypto/tls"
- "fmt"
- "io"
- "time"
-
- "log"
- )
-
- func main() {
- //注意这里要使用证书中包含的主机名称
- conn,err := tls.Dial("tcp","abc.com:8888",nil)
- if err != nil {
- log.Fatalln(err.Error())
- }
- defer conn.Close()
- log.Println("Client Connect To ",conn.RemoteAddr())
- status := conn.ConnectionState()
- fmt.Printf("%#v\n",status)
- buf := make([]byte, 1024)
- ticker := time.NewTicker(1 * time.Millisecond * 500)
- for {
- select {
- case <-ticker.C:
- {
- _,err = io.WriteString(conn,"hello")
- if err != nil {
- log.Fatalln(err.Error())
- }
- len,err := conn.Read(buf)
- if err != nil {
- fmt.Println(err.Error())
- } else {
- fmt.Println("Receive From Server:",string(buf[:len]))
- }
- }
- }
- }
-
- }