簡體   English   中英

Golang HTTP x509:由未知權限簽名的證書錯誤

[英]Golang HTTP x509: certificate signed by unknown authority error

我正在使用 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
}

有沒有另一種方法可以解決這個問題,而不必忽略證書驗證? 如果沒有,我在代碼中做錯了什么?

Golang 使用操作系統證書存儲。 以下注釋表明 Go 在 Windows 上使用 Windows 商店, 類似於 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 中,選擇File > Add/Remove Snap-in
  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 文檔還包括屏幕截圖。

你這樣做:

// NewAPIClient - creates a new API client
func NewAPIClient() Client {
    c := &APIClient{}

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkyVerify: true}, // <--- Problem
    }
    c.client = &http.Client{Transport: tr}
    return c
}

但它是InsecureSkipVerify而不是InsecureSkyVerify

但是要小心,因為InsecureSkipVerify控制客戶端是否驗證服務器的證書鏈和主機名。 如果InsecureSkipVerify為真,crypto/tls接受服務器提供的任何證書和該證書中的任何主機名。 在這種模式下,除非使用自定義驗證,否則 TLS 容易受到中間機攻擊。 這應該僅用於測試或與VerifyConnection 或VerifyPeerCertificate 結合使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM