为什么cURL无法在Windows上正确验证证书?


30

当我尝试在Windows上使用Curl来检索httpsURL时,出现了可怕的“连接错误(60)”。

在此处输入图片说明

确切的错误消息是:

curl:(60)SSL证书问题,请验证CA证书是否正确。详细信息:
错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败
更多详细信息,请参见:http ://curl.haxx.se/docs/sslcerts.html

如何解决呢?


SU不喜欢标题中的“问题”一词,因为它不是描述性的。如果您找不到一个没有“问题”一词的重新命名标题的方法,则您就没有足够的努力。:)
加勒特

1
这是我要询问的消息的确切报价。我不想尝试删除该单词,这对于搜索索引来说很重要。
Cheeso 2012年

@Cheeso:帖子内容也会被索引,搜索您问题的人会在标题下的说明中看到它。
Tamara Wijsman 2012年

Answers:


36

我不知道为什么,但是我没有一次找到所有这些信息。

  1. 下载Curl的SSL感知版本,或自己构建SSL感知版本。

  2. http://curl.haxx.se/docs/caextract.html中,下载cacert.pem文件。

  3. 将curl.exe和.pem文件放在同一目录中。

  4. cacert.pem文件重命名为curl-ca-bundle.crt

  5. 重新运行curl.exe!


编辑:

还有其他方法可以解决问题。这种特殊方式依赖于Curl制造商生产的证书。这可能不是您想要的,尤其是对于SSL站点使用的证书的知名证书颁发机构(例如您公司唯一的权威)不为人所知的情况可能不起作用。在这种情况下,您将要生成自己的curl-ca-bundle.crt文件。您可以使用certreq.exe和openssl.exe从IE / Windows存储中导出这样的证书,然后分别转换为pem格式。


1
谢谢!!!我最近尝试对HTTPS进行URL查询,并花了很长时间试图弄清楚如何使其工作。像您一样,我也不得不检查各种来源的信息,但不幸的是,我没有找到有关必须从cURL站点下载证书文件的部分(我看到了很多有关从目标站点下载证书的内容,但不是这个)。
Synetech 2012年

很高兴它有所帮助。
Cheeso 2012年

将其重命名为curl-ca-bundle.crt有什么意义?它是Windows专用的吗?
nawfal

谢谢!我在Windows 7上使用curl标记WinSSL。根据文档链接,如此标记的版本应该只使用系统的证书即可工作。但是,在遵循您的解决方案之前,我一直遇到错误。
乔治

但是,如果最终用户没有管理员权限,则他们将无法将新证书放在属于系统的文件夹中。或者,用户可以使用环境变量set CURL_CA_BUNDLE=<path to crt>。确保文件格式正确。即使您有多个curl安装(例如git,vagrant ...),此方法也将有效
Aaron C

6

我创建了一个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]::AuthRoot, $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-----"
}

2

实际上,我们在Typheous / Ruby中也遇到了同样的问题。解决方案是下载cacert.pem并将其保存到C:\ Windows \ System32(或Windows所在的任何位置)。之后,我们设置一个全局环境变量,如此处所述其中“变量名”必须CURL_CA_BUNDLE为该变量,“变量值”为该文件的路径%SystemRoot%\System32\cacert.pem

现在,启动新的CMD会话时,您可以仅使用Typheous / Libcurl来验证SSL连接。我已经在Windows 8.1上成功尝试过此操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.