Dlaczego cURL nie może poprawnie zweryfikować certyfikatu w systemie Windows?

30

Kiedy próbuję użyć Curl w systemie Windows, aby pobrać httpsadres URL, pojawia się przerażający „błąd połączenia (60)”.

wprowadź opis zdjęcia tutaj

Dokładny komunikat o błędzie to:

curl: (60) Problem z certyfikatem SSL, sprawdź, czy certyfikat CA jest OK. Szczegóły:
błąd: 14090086: Procedury SSL: SSL3_GET_SERVER_CERTIFICATE: weryfikacja certyfikatu nie powiodła się
Więcej szczegółów tutaj: http://curl.haxx.se/docs/sslcerts.html

Jak to rozwiązać?

Cheeso
źródło
SU nie lubi słowa „problem” w tytule, ponieważ nie jest opisowe. Jeśli nie możesz znaleźć sposobu, aby powtórzyć swój tytuł bez słowa „problem”, nie próbujesz wystarczająco mocno. :)
Garrett
1
jest to dokładny cytat wiadomości, o którą pytam. Nie chcę próbować usuwać tego słowa, jest to ważne słowo do indeksowania wyszukiwania.
Cheeso
@Cheeso: Treść wpisu również zostanie zindeksowana, ktoś szukający Twojego pytania zobaczy go w opisie pod tytułem.
Tamara Wijsman

Odpowiedzi:

36

Nie wiem dlaczego, ale nie znalazłem tych informacji w jednym miejscu.

  1. Pobierz wersję Curl obsługującą SSL lub sam skompiluj wersję obsługującą SSL.

  2. Z http://curl.haxx.se/docs/caextract.html Pobierz plik cacert.pem.

  3. Umieść curl.exe i plik .pem w tym samym katalogu.

  4. Zmień nazwę cacert.pempliku nacurl-ca-bundle.crt

  5. Uruchom ponownie curl.exe!


EDYTOWAĆ:

Istnieją inne sposoby rozwiązania problemu. ten szczególny sposób opiera się na cacert wyprodukowanym przez twórcę Curl. Może to nie być to, czego chcesz, a w szczególności może nie działać w przypadkach, gdy masz mniej znany organ certyfikujący (taki jak organ znany tylko twojej korporacji) dla certyfikatu używanego przez witrynę SSL . W takim przypadku będziesz chciał wygenerować własny curl-ca-bundle.crtplik. Możesz użyć certreq.exe i openssl.exe, aby wyeksportować taki certyfikat ze sklepu IE / Windows, a następnie odpowiednio przekonwertować na format pem.

Cheeso
źródło
1
Dziękuję Ci!!! Ostatnio próbowałem skleić HTTPS i miałem trochę czasu, próbując wymyślić, jak go uruchomić. Podobnie jak ty, ja również musiałem sprawdzić informacje w różnych źródłach, ale niestety nie znalazłem części o konieczności pobierania pliku cert z witryny cURL (widziałem wiele rzeczy na temat pobierania certyfikatu z witryny docelowej, ale nie to).
Synetech
Cieszę się, że pomogło.
Cheeso
Po co zmieniać nazwę na curl-ca-bundle.crt? Czy to jest specyficzne dla systemu Windows?
nawfal
Dzięki! Używałem curloznaczonego WinSSLna Windows 7. Zgodnie z linkiem do dokumentacji, tak oznaczone wersje powinny po prostu działać z wykorzystaniem certyfikatów systemu. Jednak pojawiał się błąd, dopóki nie zastosowałem się do twojego rozwiązania.
George
Jeśli jednak użytkownik końcowy nie ma praw administratora, nie będzie mógł umieścić nowego certyfikatu w folderach należących do systemu. Alternatywnie użytkownik może użyć zmiennej środowiskowej set CURL_CA_BUNDLE=<path to crt>. Upewnij się, że format pliku jest prawidłowy. Ta metoda zadziała, nawet jeśli masz wiele curlinstalacji, np. Git, włóczęga ...
Aaron C
6

Utworzyłem skrypt PowerShell, który jest w stanie zapisać ca-cert.crtplik na podstawie certyfikatów CA zainstalowanych w magazynie certyfikatów Windows (CurrentUser lub LocalMachine). Uruchom skrypt w następujący sposób:

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

Spowoduje to utworzenie curl-ca-cert.crtpliku, który powinien być przechowywany w tym samym katalogu co, curl.exei powinieneś być w stanie zweryfikować te same witryny, jak możesz w aplikacjach Windows (pamiętaj, że ten plik może być również używany git).

„Oficjalny” skrypt można znaleźć na GitHub , ale początkowa wersja znajduje się tutaj w celach informacyjnych:

[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-----"
}
Ramon de Klein
źródło
2

W rzeczywistości mieliśmy ten sam problem z Typheous / Ruby. Rozwiązaniem było pobranie pliku cacert.pem i zapisanie go w folderze C: \ Windows \ System32 (lub innym systemie Windows). Następnie ustawiamy globalną zmienną środowiskową, taką jak opisana tutaj, gdzie musi być „Nazwa zmiennej”, CURL_CA_BUNDLEa „Wartość zmiennej” ścieżka do pliku %SystemRoot%\System32\cacert.pem.

Podczas rozpoczynania nowej sesji CMD możesz teraz po prostu użyć funkcji Typheous / Libcurl do uwierzytelnienia połączeń SSL. Z powodzeniem wypróbowałem to w systemie Windows 8.1.

Jaskółka oknówka
źródło