新聞中心
安全傳輸層協(xié)議 TLS,以前稱(chēng)為 SSL(Secure Sockets Layer) ,由于HTTPS的推出受到了很多人的歡迎。但是正如TLS的名稱(chēng) Transport Layer Security 所示的那樣,它實(shí)際上是獨(dú)立于 HTTP,一個(gè)更深入的安全協(xié)議,我們可以將 TLS 視為 TCP 的安全版本,其提供了對(duì) socket 通信進(jìn)行加密和簽名的功能。在我們的日常開(kāi)發(fā)中,會(huì)將 gRPC 協(xié)議運(yùn)行在TLS之上以確保安全。

站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到南票網(wǎng)站設(shè)計(jì)與南票網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:成都網(wǎng)站建設(shè)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋南票地區(qū)。
今天我們來(lái)了解一下如何創(chuàng)建一個(gè)通過(guò) TLS 加密的 socket 服務(wù)。
1.TLS socket server
服務(wù)端示例
- func main() {
- port := flag.String("port", "8360", "listening port")
- certFile := flag.String("cert", "cert.pem", "certificate PEM file")
- keyFile := flag.String("key", "key.pem", "key PEM file")
- flag.Parse()
- cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
- if err != nil {
- log.Fatal(err)
- }
- config := &tls.Config{Certificates: []tls.Certificate{cert}}
- log.Printf("listening on port %s\n", *port)
- l, err := tls.Listen("tcp", ":"+*port, config)
- if err != nil {
- log.Fatal(err)
- }
- defer l.Close()
- for {
- conn, err := l.Accept()
- if err != nil {
- log.Fatal(err)
- }
- log.Printf("accepted connection from %s\n", conn.RemoteAddr())
- go func(c net.Conn) {
- io.Copy(c, c)
- c.Close()
- log.Printf("closing connection from %s\n", conn.RemoteAddr())
- }(conn)
- }
- }
這個(gè)服務(wù)端程序接受來(lái)自多個(gè)客戶(hù)端并發(fā)請(qǐng)求,并向客戶(hù)端發(fā)送的所有的鏡像數(shù)據(jù)。和非TLS服務(wù)相比,這里用 tls.Listen 替換了 net.Listen,同時(shí)需要提供一個(gè)可用的 tls.Config,我們可以使用 mkcert 命令來(lái)生成證書(shū)和密鑰對(duì)文件。
2.TLS socket client
客戶(hù)端示例:
- func main() {
- port := flag.String("port", "8360", "port to connect")
- certFile := flag.String("certfile", "cert.pem", "trusted CA certificate")
- flag.Parse()
- cert, err := os.ReadFile(*certFile)
- if err != nil {
- log.Fatal(err)
- }
- certPool := x509.NewCertPool()
- if ok := certPool.AppendCertsFromPEM(cert); !ok {
- log.Fatalf("unable to parse cert from %s", *certFile)
- }
- config := &tls.Config{RootCAs: certPool}
- conn, err := tls.Dial("tcp", "localhost:"+*port, config)
- if err != nil {
- log.Fatal(err)
- }
- _, err = io.WriteString(conn, "Hello simple secure Server\n")
- if err != nil {
- log.Fatal("client write error:", err)
- }
- if err = conn.CloseWrite(); err != nil {
- log.Fatal(err)
- }
- buf := make([]byte, 256)
- n, err := conn.Read(buf)
- if err != nil && err != io.EOF {
- log.Fatal(err)
- }
- fmt.Println("client read:", string(buf[:n]))
- conn.Close()
- }
和非 TLS 客戶(hù)端相比,我們同樣也只是把 net.Dial 換成 tls.Dial, tls.Config 中填寫(xiě)的證書(shū)可以選擇權(quán)威 ca 頒發(fā)的證書(shū),也可以使用自簽名證書(shū)。
3.證書(shū)鏈
一般來(lái)說(shuō),我們將自己生成的 CSR 提交給簽名商,他們用中級(jí)證書(shū)機(jī)構(gòu)的私鑰 Private Key 給我們的簽名成證書(shū),Root CA 通過(guò)它的私鑰對(duì)中級(jí)機(jī)構(gòu)提交的CSR進(jìn)行簽名。
證書(shū)頒發(fā)機(jī)構(gòu)是一個(gè)樹(shù)形結(jié)構(gòu)的。比如在驗(yàn)證我們證書(shū)X的有效性的時(shí)候,會(huì)一層層的去尋找頒發(fā)者的證書(shū),直到自簽名的根證書(shū),然后通過(guò)相應(yīng)的公鑰再反過(guò)來(lái)驗(yàn)證下一級(jí)的數(shù)字簽名的正確性。直到找到X證書(shū),這就是證書(shū)鏈(Certificate Chains)。
我們可以使用以下程序檢查任何服務(wù)器的證書(shū)鏈:
- func main() {
- addr := flag.String("addr", "localhost:8360", "dial address")
- flag.Parse()
- cfg := tls.Config{}
- conn, err := tls.Dial("tcp", *addr, &cfg)
- if err != nil {
- log.Fatal("TLS connection failed: " + err.Error())
- }
- defer conn.Close()
- certChain := conn.ConnectionState().PeerCertificates
- for i, cert := range certChain {
- fmt.Println(i)
- fmt.Println("Issuer:", cert.Issuer)
- fmt.Println("Subject:", cert.Subject)
- fmt.Println("Version:", cert.Version)
- fmt.Println("NotAfter:", cert.NotAfter)
- fmt.Println("DNS names:", cert.DNSNames)
- fmt.Println("")
- }
- }
給定IP地址后,啟動(dòng)程序后會(huì)與服務(wù)器建立一條 TLS 連接,并上報(bào)其使用的證書(shū)給服務(wù)端。如果我們使用未處理過(guò)的自簽的證書(shū),TLS 服務(wù)端驗(yàn)證是通不過(guò)的。所以我們需要權(quán)威ca 頒發(fā)的證書(shū),或者使用 mkcert 為我們的服務(wù)器生成證書(shū)來(lái)使他生效。
打開(kāi)終端,執(zhí)行 mkcert 命令:
- kangkai-iri ./mkcert localhost
- kangkai-iri go run tls-socket-server.go -cert localhost.pem -key localhost-key.pem
新打開(kāi)一個(gè)終端,運(yùn)行 tls-dial-port:
- kangkai-iri go run tls-dial-port.go -addr localhost:4040
我們看到生成了證書(shū) mkcert。由于 mkcert 將此證書(shū)添加到服務(wù)器的系統(tǒng)根存儲(chǔ)中,直接使用 tls.Dial 將信任該證書(shū)。
網(wǎng)站欄目:使用Go實(shí)現(xiàn)TLSsocketserver
轉(zhuǎn)載來(lái)于:http://m.fisionsoft.com.cn/article/cceghdd.html


咨詢(xún)
建站咨詢(xún)
