代码
测试

用go写后端https服务时,需要定位https包中的内容是否符合预期。

有涉猎的朋友应该了解过https有一种keylog技术,它允许在HTTPS连接中捕获和记录SSL或TLS会话密钥,以便于调试和分析加密流量。

本文将的就是通过可控制开启和关闭的keylog功能,提供安全便捷的调试方法。

代码
服务端代码如下

package main

 import ( "crypto/tls" "github.com/gin-gonic/gin" "hbp_common/Base" "io" "log" "net/http" "os" "path/filepath" )var tlsConfig *tls.Config var keylogpath stringconst ( ApiCertPath = "/root/testssl/cert.pem" ApikeyPath= "/root/testssl/key.pem" )func main() { route := gin.Default() ​ route.GET("/hello", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"result": "word"}) })ListenAndSeverTls(route) }func SetEnableKeyLog(ctx *gin.Context) { enable := ctx.Param("enable") if enable == "enable" { var err error tlsConfig.KeyLogWriter, err = KeyLogWrite(keylogpath) if err != nil { ctx.AbortWithStatus(http.StatusForbidden) return } } else if enable == "disable" { tlsConfig.KeyLogWriter = nil err := os.RemoveAll(keylogpath) if err != nil { ctx.AbortWithStatus(http.StatusForbidden) return } } else { ctx.AbortWithStatus(http.StatusBadRequest) return } ctx.Status(http.StatusOK) }func KeyLogWrite(path string) (io.Writer, error) { keyLogFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatal(err.Error()) } return keyLogFile, err }func ListenAndSeverTls(route *gin.Engine) { defer Base.SafePanic() keylogpath = filepath.Dir(ApiCertPath) + "/keylog"// 加载证书和密钥 cert, err := tls.LoadX509KeyPair(ApiCertPath, ApikeyPath) if err != nil { log.Panic("ListenAndSeverTls failed! LoadX509KeyPair err:[%s]", err) }// 配置TLS tlsConfig = &tls.Config{KeyLogWriter: nil} tlsConfig.Certificates = []tls.Certificate{cert} ​ listener, err := tls.Listen("tcp", ":24443", tlsConfig) if err != nil { log.Panic("ListenAndSeverTls failed! ListenTLS err:[%s]", err) } server := http.Server{Handler: route, Addr: ":24443", TLSConfig: tlsConfig}//注册keylog记录使能接口 //PUT https://localhost:8443/debug/keylog/enable 使能tls keylog //PUT https://localhost:8443/debug/keylog/disable 失能tls keylog route.PUT("/debug/keylog/:enable", SetEnableKeyLog) ​ err = server.Serve(listener) if err != nil { log.Panic("ListenAndSeverTls failed! Serve err:[%s]", err) } }

通过 //PUT https://localhost:8443/debug/keylog/enable 使能tls keylog //PUT https://localhost:8443/debug/keylog/disable 失能tls keylog

可以开启和关闭该功能,可以做到不使用使防止keylog泄露。在开启和关闭操作时可以再加上鉴权校验等操作使方法更安全。

测试

可以看到,前面收到了客户端的hello,但是我没有使能,所以没有keylog生成。

开启后便有了keylog

我在此抓了包

目前是加密的

通过ctrl+shift+p打开首选项窗口

找到Protocols中的TLS,将刚才生成的keylog路径设置到图中位置

点击ok,就可以看到https明文了


disable后会删除keylog文件,确保keylog的安全