為什麼 cURL 無法在 Windows 上正確驗證憑證?

為什麼 cURL 無法在 Windows 上正確驗證憑證?

當我嘗試在 Windows 上使用 Curl 來檢索httpsURL 時,我收到了可怕的「連接錯誤 (60)」。

在此輸入影像描述

確切的錯誤訊息是:

curl: (60) SSL 憑證問題,請驗證 CA 憑證是否正常。詳細資訊:
錯誤:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:憑證驗證失敗
更多詳細資訊:http://curl.haxx.se/docs/sslcerts.html

如何解決這個問題?

答案1

我不知道為什麼,但我沒有在一處找到所有這些資訊。

  1. 下載 Curl 的 SSL 感知版本,或自行建立 SSL 感知版本。

  2. http://curl.haxx.se/docs/caextract.html, 下載 cacert.pem 檔案。

  3. 將curl.exe 和.pem 檔案放在同一目錄中。

  4. 將檔案重新命名cacert.pemcurl-ca-bundle.crt

  5. 重新運行curl.exe!


編輯:

還有其他方法可以解決該問題。這種特殊的方式依賴 Curl 製造商產生的 cacert。這可能不是您想要的,特別是,當您的 SSL 網站使用的憑證有一個不太知名的認證機構(例如只有您的公司知道的機構)時,它可能不起作用。在這種情況下,您將需要產生自己的curl-ca-bundle.crt文件。您可以使用 certreq.exe 和 openssl.exe 從 IE/Windows 儲存中匯出此類證書,然後分別轉換為 pem 格式。

答案2

我建立了一個 PowerShell 腳本,該腳本能夠ca-cert.crt根據 Windows 憑證儲存(CurrentUser 或 LocalMachine)中安裝的 CA 憑證寫入檔案。像這樣運行腳本:

CreateCaCert.ps1 -StoreLocation CurrentUser | Out-File -Encoding utf8 curl-ca-cert.crt

這將建立curl-ca-cert.crt應儲存在與 Windows 應用程式相同的目錄中的文件,curl.exe並且您應該能夠驗證與 Windows 應用程式中相同的網站(請注意,該文件也可以由git)使用。

「官方」腳本可以在GitHub,但這裡列出了初始版本以供參考:

[CmdletBinding()]
Param(
    [ValidateSet(
        [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser,
        [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)]
    [string]
    $StoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
)

$maxLineLength = 77

# Open the store
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store ([System.Security.Cryptography.X509Certificates.StoreName]::Root, $StoreLocation)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly);

# Write header
Write-Output "# Root certificates ($StoreLocation) generated at $(Get-Date)"

# Write all certificates
Foreach ($certificate in $store.Certificates)
{
    # Start with an empty line
    Write-Output ""

    # Convert the certificate to a BASE64 encoded string
    $certString = [Convert]::ToBase64String($certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert));

    # Write the actual certificate
    Write-Output "# Friendly name: $($certificate.FriendlyName)"
    Write-Output "# Issuer:        $($certificate.Issuer)"
    Write-Output "# Expiration:    $($certificate.GetExpirationDateString())"
    Write-Output "# Serial:        $($certificate.SerialNumber)"
    Write-Output "# Thumbprint:    $($certificate.Thumbprint)"
    Write-Output "-----BEGIN CERTIFICATE-----"
    For ($i = 0; $i -lt $certString.Length; $i += $maxLineLength)
    {
        Write-Output $certString.Substring($i, [Math]::Min($maxLineLength, $certString.Length - $i))
    }
    Write-Output "-----END CERTIFICATE-----"
}

答案3

事實上,我們在 Typheous/Ruby 上也遇到了同樣的問題。解決方案是下載cacert.pem並將其儲存到 C:\Windows\System32(或 Windows 所在的任何位置)。之後我們設定一個全域環境變數就像這裡描述的那樣其中「變數名稱」必須是CURL_CA_BUNDLE,「變數值」必須是檔案的路徑%SystemRoot%\System32\cacert.pem

當啟動新的 CMD 會話時,您現在可以使用 Typheous/Libcurl 來驗證 SSL 連線。我已經在 Windows 8.1 上成功嘗試過此操作。

相關內容