mkcert 是最省事的本地可信证书方案,它在系统根证书库安装专用 CA 并签发 localhost 或自定义域名证书,Go 需用未加密 PEM 格式证书和私钥,客户端需手动加载 rootCA.pem 或禁用校验(仅开发)。

用 mkcert 生成可信本地证书最省事
macOS 和 Windows 上直接信任自签名证书很麻烦,浏览器会持续报错;mkcert 是目前最轻量、最可靠的本地 CA 工具,它会在系统根证书库中安装一个仅用于本地的 CA,并用它签发 localhost 或自定义域名(如 dev.local)的证书,浏览器和 curl 都默认信任。
- 安装:
brew install mkcert(macOS),或从 GitHub releases 下载预编译二进制 - 初始化本地 CA:
mkcert -install(需输入系统密码) - 生成证书对:
mkcert localhost 127.0.0.1 ::1→ 输出localhost.pem(证书)和localhost-key.pem(私钥) - Golang 中直接加载:
http.ListenAndServeTLS(":8443", "localhost.pem", "localhost-key.pem", nil)
Go 的 http.ListenAndServeTLS 对证书格式有硬性要求
ListenAndServeTLS 不接受 PKCS#12(.pfx)、PEM 混合格式或带密码的私钥。必须是两个独立、未加密、标准 PEM 格式的文件:
- 证书文件(
.pem或.crt):以-----BEGIN CERTIFICATE-----开头,包含完整证书链(如需中间证书,需追加在服务器证书之后) - 私钥文件(
.pem或.key):以-----BEGIN RSA PRIVATE KEY-----或-----BEGIN EC PRIVATE KEY-----开头,且不能加密(即不能含Proc-Type: 4,ENCRYPTED) - 若用 OpenSSL 转换,确保执行:
openssl rsa -in key-encrypted.pem -out key-unencrypted.pem
调试时绕过 Go HTTP 客户端的证书校验(仅限开发)
当你的 Go 程序作为 HTTP 客户端调用另一个本地 HTTPS 服务(比如自己写的 backend)时,若对方证书是 mkcert 签发的,标准 http.Client 仍可能报 x509: certificate signed by unknown authority。这是因为 Go 默认只信任系统根证书,不读取 macOS Keychain / Windows Certificate Store 中的用户级 CA。
- 临时解决(仅开发):
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - 更安全的做法:把
mkcert的根证书(通常在$(mkcert -CAROOT)/rootCA.pem)加入 Go 的 TLS 配置:rootCAs, _ := x509.SystemCertPool() rootCAs.AppendCertsFromPEM(pemBytes) // pemBytes 是 rootCA.pem 内容 tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: rootCAs}, } - 注意:
InsecureSkipVerify: true绝不能出现在生产代码里,CI/PR 检查应拦截该字符串
使用自定义域名(如 app.test)需要额外 Hosts 和证书配置
想用 https://app.test:8443 调试?光改 Hosts 不够,证书也必须覆盖该域名。
立即学习“go语言免费学习笔记(深入)”;
- 先加 Hosts:
echo "127.0.0.1 app.test" | sudo tee -a /etc/hosts - 生成证书时显式指定域名:
mkcert app.test localhost 127.0.0.1 - 浏览器访问前,确认地址栏显示锁图标且无警告;若仍有警告,清空浏览器证书缓存(Chrome:设置 → 隐私设置 → 管理证书 → 删除 “localhost” 或 “app.test” 相关条目)
- 某些 IDE(如 VS Code 的 Live Server)或代理(如 Charles)不自动信任
mkcertCA,需手动导入rootCA.pem
真正容易被忽略的是:Go 进程启动后不会自动重载证书文件,改了 .pem 必须重启服务;而浏览器可能缓存 OCSP 响应或证书吊销状态,遇到奇怪的“证书已过期”提示,先强制刷新(Cmd+Shift+R)再检查证书有效期。










