You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:在代码中手动加载信任证书

如果不想修改系统配置,可在代码中指定要信任的根证书:

  1. 将根CA证书文件(如ca.crt)放到项目目录下
  2. 修改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,提问作者Алексей Семенов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:15:41