我正在使用Golang 1.9.2创建一个客户端应用程序,但我在访问后端时遇到了一些问题。我的应用程序在最新版本的Windows和Linux中运行良好,但是当我在Windows XP上运行它时(是的,不幸的是,我必须支持Windows XP,因为我们的一些客户拒绝升级操作系统),尝试执行HTTP GET和HTTP POST时会出现以下错误:x509:由未知机构签名的证书
。
我已经使用Firefox ESR浏览器和Chromium浏览器从Windows XP内部运行相同的GET命令,并且它们都没有抱怨证书。
请注意,我的证书有效并由受信任的机构签名。
我做了一些研究,发现有些人也遇到了同样的问题,并通过忽略TLS验证来解决这个问题,方法是:
import ("net/http"; "crypto/tls")
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify : true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://someurl:443/)
所以我将这段代码添加到我的程序中,但它仍然无法正常工作。// NewAPIClient - creates a new API client
func NewAPIClient() Client {
c := &APIClient{}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkyVerify: true},
}
c.client = &http.Client{Transport: tr}
return c
}
// GetTasks - retrieves a list of tasks from the backend.
func (c *APIClient) GetTasks() ([]byte, error) {
conf := config.GetInstance()
url := fmt.Sprintf("%s/myurl", conf.GetConfig().APIUrl)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.WithError(err).Errorf("Error creating HTTP request")
return nil, err
}
// Add headers
req.Header.Add("Authorization", conf.GetConfig().APIToken)
req.Header.Add("Accept", "application/json")
log.Info("Retrieving tasks from the API")
resp, err := c.client.Do(req)
if err != nil {
log.WithError(err).Errorf("Error retrieving tasks from the backend")
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
errMsg := fmt.Sprintf("Received status: %s", resp.Status)
err = errors.New(errMsg)
log.WithError(err).Error("Error retrieving tasks from the backend")
return nil, err
}
tasks, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.WithError(err).Error("Error reading tasks response body")
return nil, err
}
log.Info("The tasks were successfully retrieved")
return tasks, nil
}
有没有另一种方法可以解决这个问题,而不必忽略证书验证?如果没有,那么我的代码哪里做错了吗?
pool, err := x509.SystemCertPool()
,然后使用池的AddCert()
函数添加CA证书,最后在TLS配置中使用该池进行请求。【更多信息】(https://golang.org/pkg/crypto/x509/#SystemCertPool) - SvenskungankaAddCert()
添加证书时,它们会被永久添加还是每次我的应用程序运行时都需要重新添加? - Felipex509.SystemCertPool()
函数都会返回系统证书池的 副本,对其进行的任何更改仅在内存中保留,而不写入磁盘。这就是为什么您需要设置安全的方式来自动更新证书以防止过期。说实话,为了获得 Windows XP 支持,需要做很多工作。这就是 Web 浏览器所做的,它们保留自己的证书池,并忽略系统的证书池。 - Svenskunganka