Golang 使用 crypto-tls 包實現 SSL-TLS 協議的 TCP 服務器
在網絡通信中,安全性至關重要。SSL/TLS 協議是一種廣泛使用的加密通信協議,用於保護敏感數據的傳輸。在本文中,我們將介紹如何使用 Golang 編程語言實現一個 SSL/TLS 協議的服務器,以確保我們的網絡通信是安全可靠的。
1. SSL/TLS 簡介
SSL/TLS(Secure Sockets Layer/Transport Layer Security)是一組加密協議,用於在計算機網絡上提供安全的數據傳輸。它們位於傳輸層,確保在客戶端和服務器之間的通信過程中數據的機密性、完整性和身份驗證。
2. Golang 中的 SSL/TLS 支持
Golang 是一種簡潔而高效的編程語言,它提供了強大的網絡編程能力和對 SSL/TLS 的支持。標準庫中的 "crypto/tls" 包提供了 SSL/TLS 協議的實現,使我們能夠輕鬆地構建安全的網絡應用程序。
3. 使用 openssl 創建數字證書
創建根證書
# 生成根證書私鑰
openssl genrsa -out ca.key 2048
# 使用私鑰創建根證書
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt
創建 SSL 證書
# 生成SSL私鑰
openssl genrsa -out server.key 2048
# 使用私鑰生成證書籤發請求
openssl req -new -key server.key -out server.csr
# 創建簽署證書相關目錄和文件
mkdir demoCA &&cd demoCA&&mkdir newcerts&&echo '10' > serial &&touch index.txt&&cd ..
# 使用根證書籤署SSL證書
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
# 查看證書
openssl x509 -in server.crt -noout -text
Mac 系統如果根證書籤署 SSL 證書時報錯:
Using configuration from /private/etc/ssl/openssl.cnf
variable lookup failed for ca::default_ca
140704333022784:error:0EFFF06C:configuration file routines:CRYPTO_internal:no value:/AppleInternal/Library/BuildRoots/c2cb9645-dafc-11ed-aa26-6ec1e3b3f7b3/Library/Caches/com.apple.xbs/Sources/libressl/libressl-3.3/crypto/conf/conf_lib.c:322:group=ca name=default_ca
是因爲系統默認的 openssl 使用的 / private/etc/ssl/openssl.cnf 配置文件中缺失 default_ca 的配置。
解決方法:使用 brew 安裝的 openssl 而不使用系統默認的 openssl, brew 安裝好 openssl 後在終端執行命令
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
4. 使用 Golang 創建 SSL/TLS 的 TCP 服務器
使用 "crypto/tls" 包,我們可以輕鬆地爲我們的服務器生成自簽名的證書,並將其用於 SSL/TLS 連接。
package main
import (
"crypto/tls"
"github.com/sirupsen/logrus"
"log"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
buffer := make([]byte, 1024)
for {
l, err := conn.Read(buffer)
if err != nil {
log.Println(err.Error())
break
}
logrus.Infoln("Receive Data: %s\n", string(buffer[:l]))
}
logrus.Infoln("Client " + conn.RemoteAddr().String() + " Connection Closed.....")
}
func main() {
port := "8888"
crt, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Fatalln(err.Error())
}
tlsConfig := &tls.Config{}
tlsConfig.Certificates = []tls.Certificate{crt}
ln, err := tls.Listen("tcp", ":"+port, tlsConfig)
if err != nil {
logrus.Fatalf("TCP server failed to listen on port %s. Error: %s", port, err.Error())
}
logrus.Infof("TCP server listening on port %s", port)
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
logrus.Fatalf("TCP server failed to accept connection on port %s. Error: %v", port, err)
} else {
go handleConnection(conn)
}
}
}
運行結果:
INFO[0000] TCP server listening on port 8888
INFO[0221] Receive Data: %s
Hello SSL/TLS
2023/06/25 21:33:52 EOF
INFO[0221] Client 127.0.0.1:50909 Connection Closed.....
INFO[0271] Receive Data: %s
Hello SSL/TLS
2023/06/25 21:34:41 EOF
INFO[0271] Client 127.0.0.1:50915 Connection Closed.....
5. 客戶端代碼
客戶端需要配置 InsecureSkipVerify 參數,該參數表示客戶端跳過對證書鏈的校驗,因爲 CA 證書是不是自己生成的,不是系統信任的證書。
6. 結論
通過使用 Golang 的 "crypto/tls" 包,我們成功地實現了一個使用 SSL/TLS 協議的 TCP 服務器。通過加載證書和私鑰,我們確保了安全的通信連接,並且可以進行安全的數據傳輸。
SSL/TLS 協議在保護網絡通信方面起着重要作用,它使得數據在傳輸過程中免受竊聽和篡改的風險。通過掌握 Golang 中的 SSL/TLS 支持,我們可以構建安全可靠的網絡應用程序。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/tfeFhDEMrYQUfdyZqM0qCA