为什么 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. 下载支持 SSL 的 Curl 版本,或者自行构建支持 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应存储在同一目录中的文件,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 上成功尝试过此操作。

相关内容