Golang HTTP x509:由未知权限错误签名的证书

时间:2017-11-23 22:43:15

标签: windows ssl go

我正在使用Golang 1.9.2创建一个客户端应用程序,我在访问我的后端时遇到了一些麻烦。问题是我的应用程序在最新版本的Windows和Linux中运行良好,但是当我在Windows XP上运行时(是的,不幸的是我必须支持Windows XP,因为我们的一些客户拒绝升级他们的操作系统)尝试执行HTTP GET和HTTP POST时出现此错误:x509: certificate signed by unknown authority

我在Windows XP中使用Firefox ESR浏览器和Chromium浏览器运行相同的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
}

是否有另一种方法可以解决此问题,而无需忽略证书验证?如果没有,我在代码中做错了什么?

1 个答案:

答案 0 :(得分:0)

Golang 使用操作系统证书存储。以下注释表明 Go 使用 Windows 上的 Windows 商店,similar to Linux

<块引用>

// CertGetCertificateChain 将遍历 Windows 的根存储以尝试构建经过验证的证书链

此注释和相关代码位于以下文件中:

https://golang.org/src/crypto/x509/root_windows.go

将服务器证书、中间 CA 证书和/或根 CA 证书添加到 Windows XP 证书存储区。您可以使用 IBM 发布的以下 Windows XP 说明:

<块引用>

程序

  1. 在 Windows XP 中,选择开始 > 运行以打开命令行。
  2. 在“运行”对话框中键入 mmc,然后单击确定以运行 Microsoft 管理控制台 (MMC)。
  3. 在 MMC 中,选择文件 > 添加/删除管理单元
  4. 点击添加
  5. 点击证书
  6. 点击我的用户帐户
  7. 点击完成
  8. 添加独立管理单元对话框中点击关闭
  9. 添加/删除管理单元对话框中点击确定

参考:https://www.ibm.com/docs/en/b2b-integrator/5.2?topic=xp-install-root-certificate-in-windows

GlobalSign 和 Securely 为更现代的 Windows 版本提供了类似的说明,但上面的 IBM 链接专门用于 Windows XP。下面的 Securely 文档还包括屏幕截图。