Go中CipherSuites仅作TLS 1.2及以下的白名单,不影响TLS 1.3;需配PreferServerCipherSuites:true才生效,且必须用http.Server显式配置TLSConfig,否则安全设置无效。

Go crypto/tls 中 CipherSuites 字段只起白名单作用,不是排序列表
从 Go 1.17 开始,CipherSuites 字段对 TLS 1.3 套件完全无效——Go 会自动启用 tls.TLS_AES_128_GCM_SHA256 等标准套件,且不允许干预顺序。它仅在 TLS 1.2 及以下版本中参与协商,且仅作为“允许使用哪些套件”的过滤器。
常见错误现象:CipherSuites 列表里写了 tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,但客户端仍协商出 tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256(只要服务端没禁用、客户端支持)。
- 必须配合
PreferServerCipherSuites: true才能影响 TLS 1.2 协商结果 - TLS 1.3 的套件不能手动加入
CipherSuites列表,否则会被忽略(编译不报错,但运行时无效果) - 若同时支持 TLS 1.2 和 1.3,实际生效的套件取决于客户端能力+服务端白名单+运行时自动排序逻辑
只保留 AEAD 类强加密套件,彻底剔除 CBC 模式
Go 标准库已明确弃用非 AEAD(Authenticated Encryption with Associated Data)类算法。SHA1、3DES、RC4、CBC 模式 AES(如 tls.TLS_RSA_WITH_AES_256_CBC_SHA)全部属于高风险套件,不应出现在生产配置中。
推荐保留的套件(适用于 TLS 1.2):
立即学习“go语言免费学习笔记(深入)”;
[]uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
}
- 避免混用 RSA 和 ECDSA 证书类型导致的兼容问题:如果只用 RSA 证书,就别加 ECDSA 套件
- 不推荐硬编码
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:Chacha20 在 ARM 或旧 CPU 上有优势,但现代 x86_64 通常 AES-NI 更快;Go 运行时会按需自动启用,无需显式列出 - 禁用所有带
_SHA、_SHA256(非 GCM)、_3DES_EDE_CBC后缀的套件
MinVersion + MaxVersion 必须成对设置,且不能依赖默认值
http.ListenAndServeTLS 内部硬编码了 *tls.Config,你传进去的任何 MinVersion 或 CipherSuites 都会被无视——这是最常被忽略的陷阱。生产环境必须用 http.Server 显式挂载自定义 tls.Config。
安全最小配置(禁用 TLS 1.0/1.1):
config := &tls.Config{
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS13,
PreferServerCipherSuites: true,
CipherSuites: [...] // 如上所列
}
server := &http.Server{
Addr: ":443",
TLSConfig: config,
}
- 不要只设
MinVersion: tls.VersionTLS12而留MaxVersion为 0(即零值):Go 当前会按tls.VersionTLS13处理,但行为未明确定义,未来升级可能意外启用 TLS 1.4 - 拼错常量名(如写成
tls.TLS12或"1.2")会导致编译失败或静默降级 -
tls.VersionTLS10和tls.VersionTLS11已被 Go 标记为 cryptographically broken,不应再出现于任何配置中
PreferServerCipherSuites: true 不是可选项,而是降级防护必需项
如果不设 PreferServerCipherSuites: true,客户端可无视你的 CipherSuites 白名单,自行选择它支持的任意套件(包括你没列出来的弱套件),等于白配。
该字段仅对 TLS 1.2 及以下有效,但它能阻止客户端发起降级攻击(例如谎称不支持更强套件以诱导服务器选弱套件)。
- 即使你只支持 TLS 1.3,也建议显式设为
true:Go 当前虽不依赖它,但语义清晰,且兼容未来可能的协议扩展 - 搭配
MinVersion: tls.VersionTLS12使用时,它确保 TLS 1.2 握手阶段的套件选择权在服务端 - 注意:该设置不影响 TLS 1.3 的套件协商逻辑,TLS 1.3 套件由协议强制固定,无需也无从“偏好”
http.ListenAndServeTLS 就算完成 HTTPS 配置——它根本不会读你传的 tls.Config 里的安全参数。必须亲手构造 http.Server 并赋值 TLSConfig,否则所有密码套件和版本控制都只是幻觉。


















