wireshark 结合 go 对每个请求进行 https tls tcp 内容解密
众所周知,wireshark 是一款流行的抓包软件,我们可以很方便地查看每个 TCP 包的具体信息。对于 HTTP 协议的数据,还可以查看每个协议层具体信息内容。
但是对于 HTTPS 的数据,我们只能查看 IP 层以下的数据,TLS 及以上的数据都是被加密过的,如下图所示。
在某些特殊的场景下,我们想查看这个请求的具体内容就无从下手,即使使用 findler 等代理工具,也只能查看到最终的返回数据,没法查看 TCP 具体的传输内容。
以 HTTP 中 text/event-stream 为例,使用 apiPOST 我们可以直接得到响应内容,但是这个类型的具体是什么样的,我们无从得知。
这也是我最近工作遇到的一个问题,经过不断的尝试,发现 go 的 Transport 类型中有个 TLSConfigConfig 字段,可以打印在HTTPS 请求过程中生成的密钥,具体示例代理如下
func Test_Request2(m *testing.T) { // 创建一个文件, 用于保存tls key file, err := os.OpenFile(tlsKeyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { fmt.Printf("create tls key file failed, err: %s", err) return } defer file.Close() tlsConfig := &tls.Config{ // 设置 key 保存的路径,关键之处 KeyLogWriter: file, } client.Transport = &http.Transport{ TLSClientConfig: tlsConfig, } req, err := http.NewRequest(method, url, reqData) if err != nil { fmt.Println("Error:", err) return } resp, err := client.Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() fmt.Printf("Status: %s\n", resp.Status) }
然后在 wireshark 中指定 pre-master key,具体操作如下,选中任一一条TCP数据,右击 -> Protocol Prefferences -> Transport Layer Security -> Pre Master Secret 来选择密钥的路径, 然后就可以看到解密后的数据