Golang中TLS版本设置的实现步骤
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">Golang中TLS版本设置</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1. Go源码中的TLS</a></li><li><a href="#_lab2_0_1">2. https服务端修改TLS支持版本</a></li><li><a href="#_lab2_0_2">3. 抓包验证</a></li></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>Golang中TLS版本设置</h2><p><br /><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025110709493950.jpg" /></p>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>1. Go源码中的TLS</h3>
<p>最近在看Go源码中的<span style="color:#f26522"><strong>http框架</strong></span>和<span style="color:#f26522"><strong>tls实现框架</strong></span>实现,go中的TLS实现了<strong>TLS1.0, TLS1.1, TLS1.2, TLS1.3</strong> 四个版本,还有SSL3.0版本, 不过代码中已经明确说明不再支持SSL3.0版本。</p>
<div class="jb51code"><pre class="brush:go;">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
)
</pre></div>
<p>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。</p>
<p>我最初看到的TLS握手是这样的:</p>
<p style="text-align:center"><img alt="" height="1339" src="https://img.jbzj.com/file_images/article/202511/2025110709493979.jpg" width="949" /></p>
<p>但是在看go的tls源码时,流程上报文交互有很大的差距,后来又通过断点debug的方式确定了是由于TLS版本不同导致的,这才开始了解TLS1.2 与 TLS1.3版本之间的异同,这里暂不介绍他们之间的关系。后来为了继续看TLS1.2(上图交互流程)的实现,尝试了各种浏览器、Linux中的wget, windows上的postman, eolink等,他们默认都是采用TLS1.3版本。 </p>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>2. https服务端修改TLS支持版本</h3>
<p>go代码中实现起来非常方便,http包中提供了使用默认配置的接口<code>ListenAndServeTLS</code>。它实现了一个默认的Server结构</p>
<div class="jb51code"><pre class="brush:go;">func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServeTLS(certFile, keyFile)
}
</pre></div>
<p>其中,TLS参数配置是Server结构中的一个成员:<code>TLSConfig *tls.Config</code>。因此我们只需要实现一个Server结构,然后配置其中的<code>TLSConfig *tls.Config</code>即可。</p>
<p><strong>实现如下:</strong></p>
<div class="jb51code"><pre class="brush:go;">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)
}
}
</pre></div>
<p class="maodian"><a name="_lab2_0_2"></a></p><h3>3. 抓包验证</h3>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025110709493936.jpg" /></p>
<p><strong>关于Wireshark中的TLS版本显示问题:</strong></p>
<p>wireshark标注tls所属版本,并不是通过当前报文来标注的,<strong>而是类似于会话的方式进行标注</strong>。</p>
<p>目前ClientHello报文,需要兼容TLS1.3, TLS1.2,…等多个版本,仅从ClientHello无法判断出当前的版本。TLS版本是在ServerHello中确定的。</p>
<p><strong>TLS1.2 ServerHello报文:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025110709493984.jpg" /></p>
<p><strong>TLS1.3 ServerHello报文:</strong></p>
<p style="text-align:center"><img alt="" height="646" src="https://img.jbzj.com/file_images/article/202511/2025110709493956.jpg" width="1200" /></p>
<blockquote><p>从这两张图上应该可以看出:TLS1.2与TLS1.3 的握手报文中version字段填充的都是0x0303,也就是TLS1.2版本,如果是TLS1.3,则是通过扩展字段supported_version来确定的。</p></blockquote>
頁:
[1]