Windows环境下Go语言SMTP发件报x509未知权威证书错误排查
解决Windows下Go SMTP发送邮件时x509证书信任问题
问题描述
在Windows主机上使用Go语言smtp包发送邮件时,出现错误:x509: certificate signed by unknown authority。已确认邮件服务器证书有效,怀疑是证书存储配置问题,相关代码如下:
package main import ( "crypto/tls" "fmt" "log" "net" "net/mail" "net/smtp" ) // StartTLS Email Example func main() { from := mail.Address{"", "examplt@email.com"} to := mail.Address{"", "alhaos@gmail.com"} subj := "This is the email subject" body := "This is an example body.\n With two lines." // Setup headers headers := make(map[string]string) headers["From"] = from.String() headers["To"] = to.String() headers["Subject"] = subj // Setup message message := "" for k, v := range headers { message += fmt.Sprintf("%s: %s\r\n", k, v) } message += "\r\n" + body // Connect to the SMTP Server servername := "MyServer:587" host, _, _ := net.SplitHostPort(servername) auth := smtp.PlainAuth("", "username", "pass", host) // TLS config tlsconfig := &tls.Config{ // InsecureSkipVerify: true, ServerName: host, } c, err := smtp.Dial(servername) if err != nil { log.Panic(err) } c.StartTLS(tlsconfig) // Auth if err = c.Auth(auth); err != nil { log.Panic(err) } // To && From if err = c.Mail(from.Address); err != nil { log.Panic(err) } if err = c.Rcpt(to.Address); err != nil { log.Panic(err) } // Data w, err := c.Data() if err != nil { log.Panic(err) } _, err = w.Write([]byte(message)) if err != nil { log.Panic(err) } err = w.Close() if err != nil { log.Panic(err) } c.Quit() }
解决方案
方法1:将证书导入Windows系统信任存储
Go在Windows平台默认读取系统的受信任根证书,把邮件服务器的根CA证书导入系统即可解决:
- 按下Win+R,输入
certmgr.msc打开证书管理器 - 展开「受信任的根证书颁发机构」→「证书」
- 右键点击「证书」,选择「所有任务」→「导入」
- 按照向导选择根CA证书文件,完成导入后重启Go程序重试
方法2:在代码中手动加载信任证书
如果不想修改系统配置,可在代码中指定要信任的根证书:
- 将根CA证书文件(如
ca.crt)放到项目目录下 - 修改TLS配置部分代码(需额外导入
"crypto/x509"和"os"包):
// TLS config tlsconfig := &tls.Config{ ServerName: host, } // 加载自定义根证书 caCert, err := os.ReadFile("ca.crt") if err != nil { log.Panic(err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) tlsconfig.RootCAs = caCertPool
方法3:临时跳过证书验证(仅测试用)
生产环境禁止使用,此操作会关闭证书校验,存在安全风险:
取消TLS配置中InsecureSkipVerify的注释:
tlsconfig := &tls.Config{ InsecureSkipVerify: true, ServerName: host, }
内容的提问来源于stack exchange,提问作者Алексей Семенов
相关产品推荐
相关产品推荐

