android开发分享使用Go实现TLS服务器和客户端的示例

传输层安全协议(transport layer security,缩写:tls),及其前身安全套接层(secure sockets layer,缩写:ssl)是一种安全协议,目的是为互联网通信提供安全

传输层安全协议(transport layer security,缩写:tls),及其前身安全套接层(secure sockets layer,缩写:ssl)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。

上述就是android开发分享使用Go实现TLS服务器和客户端的示例的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

ssl包含记录层(record layer)和传输层,记录层协议确定了传输层数据的封装格式。传输层安全协议使用x.509认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密钥作为会谈密钥(session key)。这个会谈密钥是用来将通信两方交换的数据做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。

android开发分享使用Go实现TLS服务器和客户端的示例并没有提供一个tls的深度教程,而是提供了两个go应用tls的简单例子,用来演示使用go语言快速开发安全网络传输的程序。

tls历史

  • 1994年早期,netscape公司设计了ssl协议(secure sockets layer)的1.0版,但是未发布。
  • 1994年11月,netscape公司发布ssl 2.0版,很快发现有严重漏洞。
  • 1996年11月,ssl 3.0版问世,得到大规模应用。
  • 1999年1月,互联网标准化组织isoc接替netscape公司,发布了ssl的升级版tls 1.0版。
  • 2006年4月和2008年8月,tls进行了两次升级,分别为tls 1.1版和tls 1.2版。最新的变动是2011年tls 1.2的修订版。

现在正在制定 tls 1.3。

证书生成

首先我们创建私钥和证书。

服务器端的证书生成

使用了”服务端证书”可以确保服务器不是假冒的。

1、 生成服务器端的私钥

  openssl genrsa -out server.key 2048  

2、 生成服务器端证书

  openssl req -new -x509 -key server.key -out server.pem -days 3650  

或者

  go run $goroot/src/crypto/tls/generate_cert.go --host localhost  

客户端的证书生成

除了”服务端证书”,在某些场合中还会涉及到”客户端证书”。所谓的”客户端证书”就是用来证明客户端访问者的身份。
比如在某些金融公司的内网,你的电脑上必须部署”客户端证书”,才能打开重要服务器的页面。
我会在后面的例子中演示”客户端证书”的使用。

3、 生成客户端的私钥

  openssl genrsa -out client.key 2048  

4、 生成客户端的证书

  openssl req -new -x509 -key client.key -out client.pem -days 3650  

或者使用下面的脚本:

  #!/bin/bash  # call this script with an email address (valid or not).  # like:  # ./makecert.sh demo@random.com  mkdir certs  rm certs/*  echo "make server cert"  openssl req -new -nodes -x509 -out certs/server.pem -keyout certs/server.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/client.key -days 3650 -subj "/c=de/st=nrw/l=earth/o=random company/ou=it/cn=www.random.com/emailaddress=$1"  

golang 例子

go package tls部分实现了 tls 1.2的功能,可以满足我们日常的应用。package crypto/x509提供了证书管理的相关操作。

服务器证书的使用

本节代码提供了服务器使用证书的例子。下面的代码是服务器的例子:

  package main  import (      "bufio"      "crypto/tls"      "log"      "net"  )  func main() {      cert, err := tls.loadx509keypair("server.pem", "server.key")      if err != nil {          log.println(err)          return      }      config := &tls.config{certificates: []tls.certificate{cert}}      ln, err := tls.listen("tcp", ":443", config)      if err != nil {          log.println(err)          return      }      defer ln.close()      for {          conn, err := ln.accept()          if err != nil {              log.println(err)              continue          }          go handleconn(conn)      }  }  func handleconn(conn net.conn) {      defer conn.close()      r := bufio.newreader(conn)      for {          msg, err := r.readstring('n')          if err != nil {              log.println(err)              return          }          println(msg)          n, err := conn.write([]byte("worldn"))          if err != nil {              log.println(n, err)              return          }      }  }  

首先从上面我们创建的服务器私钥和pem文件中得到证书cert,并且生成一个tls.config对象。这个对象有多个字段可以设置,本例中我们使用它的默认值。
然后用tls.listen开始监听客户端的连接,accept后得到一个net.conn,后续处理和普通的tcp程序一样。
然后,我们看看客户端是如何实现的:

  package main  import (      "crypto/tls"      "log"  )  func main() {      conf := &tls.config{          insecureskipverify: true,      }      conn, err := tls.dial("tcp", "127.0.0.1:443", conf)      if err != nil {          log.println(err)          return      }      defer conn.close()      n, err := conn.write([]byte("hellon"))      if err != nil {          log.println(n, err)          return      }      buf := make([]byte, 100)      n, err = conn.read(buf)      if err != nil {          log.println(n, err)          return      }      println(string(buf[:n]))  }  

insecureskipverify用来控制客户端是否证书和服务器主机名。如果设置为true,则不会校验证书以及证书中的主机名和服务器主机名是否一致。
因为在我们的例子中使用自签名的证书,所以设置它为true,仅仅用于测试目的。

可以看到,整个的程序编写和普通的tcp程序的编写差不太多,只不过初始需要做一些tls的配置。

你可以go run server.go和go run client.go测试这个例子。

客户端证书的使用
在有的情况下,需要双向认证,服务器也需要验证客户端的真实性。在这种情况下,我们需要服务器和客户端进行一点额外的配置。

服务器端:

  package main  import (      "bufio"      "crypto/tls"      "crypto/x509"      "io/ioutil"      "log"      "net"  )  func main() {      cert, err := tls.loadx509keypair("server.pem", "server.key")      if err != nil {          log.println(err)          return      }      certbytes, err := ioutil.readfile("client.pem")      if err != 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)      if err != nil {          log.println(err)          return      }      defer ln.close()      for {          conn, err := ln.accept()          if err != nil {              log.println(err)              continue          }          go handleconn(conn)      }  }  func handleconn(conn net.conn) {      defer conn.close()      r := bufio.newreader(conn)      for {          msg, err := r.readstring('n')          if err != nil {              log.println(err)              return          }          println(msg)          n, err := conn.write([]byte("worldn"))          if err != nil {              log.println(n, err)              return          }      }  }

因为需要验证客户端,我们需要额外配置下面两个字段:

  clientauth: tls.requireandverifyclientcert,  clientcas: clientcertpool,

然后客户端也配置这个clientcertpool:

  package main  import (      "crypto/tls"      "crypto/x509"      "io/ioutil"      "log"  )  func main() {      cert, err := tls.loadx509keypair("client.pem", "client.key")      if err != nil {          log.println(err)          return      }      certbytes, err := ioutil.readfile("client.pem")      if err != 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)      if err != nil {          log.println(err)          return      }      defer conn.close()      n, err := conn.write([]byte("hellon"))      if err != nil {          log.println(n, err)          return      }      buf := make([]byte, 100)      n, err = conn.read(buf)      if err != nil {          log.println(n, err)          return      }      println(string(buf[:n]))  }  

运行这两个代码go run server2.go和go run client2.go,可以看到两者可以正常的通讯,如果用前面的客户端go run client.go,不能正常通讯,因为前面的客户端并没有提供客户端证书。

更正 使用自定义的ca的例子可以参考 https://github.com/golang/net/tree/master/http2/h2demo

  make ca:  $ openssl genrsa -out rootca.key 2048  $ openssl req -x509 -new -nodes -key rootca.key -days 1024 -out rootca.pem  ... install that to firefox  make cert:  $ openssl genrsa -out server.key 2048  $ openssl req -new -key server.key -out server.csr  $ openssl x509 -req -in server.csr -ca rootca.pem -cakey rootca.key -cacreateserial -out server.crt -days 500

到此这篇关于使用go实现tls服务器和客户端的示例的文章就介绍到这了,更多相关go tls服务器和客户端内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/971558.html

(0)
上一篇 2021年12月15日
下一篇 2021年12月15日

精彩推荐