Golang中TLS版本设置

1,208 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天

Golang中TLS版本设置

@[TOC] ![在这里插入图片描述](p3-juejin.byteimg.com/tos-cn-i-k3… =400x400)

1. Go源码中的TLS

最近在看Go源码中的http框架tls实现框架实现,go中的TLS实现了TLS1.0, TLS1.1, TLS1.2, TLS1.3 四个版本,还有SSL3.0版本, 不过代码中已经明确说明不再支持SSL3.0版本。

const (
	VersionTLS10 = 0x0301
	VersionTLS11 = 0x0302
	VersionTLS12 = 0x0303
	VersionTLS13 = 0x0304

	// Deprecated: SSLv3 is cryptographically broken, and is no longer
	// supported by this package. See golang.org/issue/32716.
	VersionSSL30 = 0x0300
)

TLS 握手过程中,优先采用TLS1.3版本,然后依次是:TLS1.2, TLS1.1, TLS1.0。 当前网络上的TLS版本正处于从TLS1.1及以下版本往TLS1.2版本上升级,大多数已经开始使用TLS1.2版本。不过已经有很多应用支持TLS1.3版本,比如说浏览器(包括Chrome,IE,FireFox等主流浏览器),Postman工具、Eolinker工具等都已经支持TLS1.3。

我最初看到的TLS握手是这样的: 请添加图片描述

但是在看go的tls源码时,流程上报文交互有很大的差距,后来又通过断点debug的方式确定了是由于TLS版本不同导致的,这才开始了解TLS1.2 与 TLS1.3版本之间的异同,这里暂不介绍他们之间的关系。后来为了继续看TLS1.2(上图交互流程)的实现,尝试了各种浏览器、Linux中的wget, windows上的postman, eolink等,他们默认都是采用TLS1.3版本。 这才有了标题的需求通过配置修改go中TLS支持的版本号

2. https服务端修改TLS支持版本

go代码中实现起来非常方便,http包中提供了使用默认配置的接口ListenAndServeTLS。它实现了一个默认的Server结构

func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServeTLS(certFile, keyFile)
}

其中,TLS参数配置是Server结构中的一个成员:TLSConfig *tls.Config。因此我们只需要实现一个Server结构,然后配置其中的TLSConfig *tls.Config即可。

实现如下:

package main

import (
	"crypto/tls"
	"fmt"
	"net/http"
)

func HelloWorld(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello world")
}

func main() {/*默认情况下*/
	http.HandleFunc("/", HelloWorld)

	err := http.ListenAndServeTLS(":10443", "./cert/server.crt", "./cert/server.key", nil)
	if err != nil {
		fmt.Println(err)
	}
}

func main() {/*修改TLS版本*/
	http.HandleFunc("/", HelloWorld)

	server := &http.Server{
		Addr:    ":8443",
		Handler: nil,
		TLSConfig: &tls.Config{
			MinVersion: tls.VersionTLS12,
			MaxVersion: tls.VersionTLS12,
		},
	}

	err := server.ListenAndServeTLS("./cert/server.crt", "./cert/server.key")
	if err != nil {
		fmt.Println(err)
	}
}

3. 抓包验证

请添加图片描述

关于Wireshark中的TLS版本显示问题:

wireshark标注tls所属版本,并不是通过当前报文来标注的,而是类似于会话的方式进行标注

目前ClientHello报文,需要兼容TLS1.3, TLS1.2,...等多个版本,仅从ClientHello无法判断出当前的版本。TLS版本是在ServerHello中确定的。

  • TLS1.2 ServerHello报文请添加图片描述

  • TLS1.3 ServerHello报文请添加图片描述

从这两张图上应该可以看出:TLS1.2与TLS1.3 的握手报文中version字段填充的都是0x0303,也就是TLS1.2版本,如果是TLS1.3,则是通过扩展字段supported_version来确定的

这一点刚开始学TLS的时候有点小困惑......