TLS/SSL证书有效期日期异常问题求助(非www/三级域名场景)
问题分析与解决方法
你遇到的问题核心有两个:SNI配置缺失和未正确选取目标证书。
1. 问题根源
现在绝大多数HTTPS服务器都是虚拟主机,多个域名共享同一个IP。TLS握手时必须通过**SNI(Server Name Indication)**告诉服务器你要访问的具体域名,否则服务器会返回默认证书(大概率和你要查询的域名不匹配),自然显示的有效期就不对了。你的代码里没有设置ServerName,只有访问www域名时刚好命中默认证书,换成其他域名就拿到了错误的证书。
另外,PeerCertificates返回的是完整的证书链:第一个元素是颁发给目标域名的终端证书,后面的是用于验证证书合法性的中间证书。你现在遍历所有证书,很可能误把中间证书的有效期当成了目标证书的。
2. 修复后的代码
package main import ( "crypto/tls" "fmt" "log" "strings" ) func getCertInfo(domain string) { // 分离域名和端口,确保ServerName是纯域名 targetDomain := domain if strings.Contains(domain, ":") { targetDomain = strings.Split(domain, ":")[0] } conf := &tls.Config{ InsecureSkipVerify: true, ServerName: targetDomain, // 关键:配置SNI,让服务器返回对应域名的证书 } conn, err := tls.Dial("tcp", domain, conf) if err != nil { log.Printf("拨号失败: %v", err) return } defer conn.Close() certs := conn.ConnectionState().PeerCertificates if len(certs) == 0 { log.Println("未获取到证书") return } // 只处理第一个证书(直接颁发给目标域名的终端证书) cert := certs[0] fmt.Printf("域名列表: %s\n\n", cert.DNSNames) fmt.Printf("颁发机构: %s\n\n", cert.Issuer) fmt.Printf("生效时间: %v\n\n", cert.NotBefore.Format("2006年1月2日 15:04")) fmt.Printf("过期时间: %s\n\n", cert.NotAfter.Format("2006年1月2日 15:04")) fmt.Printf("颁发机构通用名: %s\n\n", cert.Issuer.CommonName) fmt.Println("-----------------------------------------") } func main() { // 测试不同类型的域名 getCertInfo("www.google.com:443") getCertInfo("google.com:443") getCertInfo("mail.google.com:443") }
3. 关键修改点
- 新增
ServerName配置:强制告诉服务器要访问的域名,确保返回对应证书。 - 只读取
PeerCertificates[0]:直接获取目标域名的终端证书,避免中间证书的有效期干扰。 - 增加域名端口分离逻辑:保证
ServerName是纯域名,不带端口号,符合SNI规范。
补充提醒
InsecureSkipVerify: true会跳过证书合法性验证,仅适合测试场景使用,生产环境务必关闭,否则会引入安全风险。
内容的提问来源于stack exchange,提问作者SlothyTheHutt
相关产品推荐
相关产品推荐

