使用Golang httptest TLS时测试证书出现Bad Certificate错误
Golang httptest TLS测试提示证书无效(Bad Certificate)的原因及解决办法
核心原因
你遇到的「当前时间早于证书生效时间2小时」错误,本质是证书的生效时间(Not Before字段)为UTC时区时间,而测试时的UTC时间尚未达到该生效时间,差2小时的情况通常是以下两种场景导致:
- 生成证书时用了本地时区时间而非UTC时间设置生效时间,比如你的本地时区是UTC+2,用本地当前时间生成证书,证书的Not Before会比实际UTC时间晚2小时,导致UTC时间还没到生效点;
- Shell脚本生成证书时,误将生效时间设置为未来2小时(比如参数写错,用了
+2 hours的相对时间)。
排查与解决步骤
1. 验证证书有效期
先通过openssl命令查看证书的UTC时间有效期:
openssl x509 -in cert.pem -text -noout | grep -A 2 "Validity"
输出会显示类似以下内容:
Validity Not Before: Oct 10 08:00:00 2024 GMT Not After : Oct 10 08:00:00 2025 GMT
同时用UTC时间对比:
date -u
如果Not Before比当前UTC时间晚2小时,就坐实时区设置错误的问题。
2. 修正证书生成脚本
生成证书时强制使用UTC时间设置生效时间,避免时区偏差。例如openssl命令可以这样写:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj "/CN=localhost" \ -startdate $(date -u +%Y%m%d%H%M%SZ)
其中-startdate $(date -u +%Y%m%d%H%M%SZ)明确用UTC时间作为证书生效起始点,确保生成的证书立即生效。
3. 确保httptest正确使用证书
在测试代码中加载证书并配置Server的TLS,同时客户端需正确处理证书信任(测试环境可临时跳过验证):
import ( "net/http" "net/http/httptest" "crypto/tls" "testing" ) func TestTLSEndpoint(t *testing.T) { // 加载自定义证书和密钥 cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") if err != nil { t.Fatalf("Failed to load cert: %v", err) } // 创建未启动的Server,配置TLS handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("HTTPS test passed")) }) server := httptest.NewUnstartedServer(handler) server.TLS = &tls.Config{Certificates: []tls.Certificate{cert}} server.StartTLS() defer server.Close() // 配置客户端信任证书(或测试环境跳过验证) client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, // 仅测试环境使用,生产环境需替换为信任根证书 }, }, } // 发送HTTPS请求 resp, err := client.Get(server.URL) if err != nil { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200, got %d", resp.StatusCode) } }
内容的提问来源于stack exchange,提问作者Andy5
相关产品推荐
相关产品推荐

