erro cURL 60: certificado SSL: não é possível obter o certificado do emissor local

232

Uso o WAMP em um ambiente de desenvolvimento local e estou tentando cobrar um cartão de crédito, mas recebo a mensagem de erro:

cURL error 60: Problema no certificado SSL: não é possível obter o certificado do emissor local

Pesquisei bastante no Google e muitas pessoas estão sugerindo que eu baixe este arquivo: cacert.pem , coloque-o em algum lugar e faça referência a ele no meu php.ini. Esta é a parte do meu php.ini:

curl.cainfo = "C:\Windows\cacert.pem"

No entanto, mesmo depois de reiniciar o servidor várias vezes e alterar o caminho, recebo a mesma mensagem de erro.

Eu uso o WAMP dos módulos Apache e tenho o ssl_module ativado. E a partir das extensões PGP, tenho o php_curl ativado.

Ainda a mesma mensagem de erro. Por que isso está acontecendo?

Agora estou seguindo esta correção: Como corrigir PHP CURL Error 60 SSL

O que sugere que eu adicione essas linhas às minhas opções de cURL:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);

Onde adiciono opções ao meu cURL? Aparentemente, não através da linha de comando, pois minha CLI não encontra o comando "curl_setopt"

EDITAR

Este é o código que estou executando:

public function chargeStripe()
{
    $stripe = new Stripe;
    $stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));

    $charge = $stripe->charges()->create([
        'amount'   => 2900,
        'customer' => Input::get('stripeEmail'),
        'currency' => 'EUR',
    ]);

    dd($charge);

    // echo $charge[Input::get('stripeToken')];


    return Redirect::route('step1');
}
Amor e felicidade
fonte
Supondo que não haja problemas com seu código, pode ser seu firewall. Tente desativar o firewall para testar.
Waqar ul Islam
não lhe dei resposta para esta pergunta aqui ? :)
Limon Monte
@limonte possível, teve que mudar de projeto e provavelmente tem o mesmo problema com o novo projeto. Voltará ao problema do guzzle e talvez seja a mesma correção. brb
LoveAndHappiness
1
Você já experimentou a versão mais recente do stripe? Eu vejo uma mensagem que mudou alguma coisa a ver com certs ... cometer github.com/stripe/stripe-php/commit/...
thelastshadow
1
@LoveAndHappiness você tem a solução para este problema? Estou enfrentando o mesmo erro com tarja. Entre em contato se você tiver alguma solução.
Dev

Respostas:

515

Solução de trabalho assumindo que você esteja no Windows usando XAMPP:

Servidor XAMPP

  1. Semelhante para outro ambiente
    • faça o download e extraia o cacert.pem aqui (um formato / arquivo de arquivo limpo)

https://curl.haxx.se/docs/caextract.html

  1. Coloque-o aqui no seguinte diretório.

C: \ xampp \ php \ extras \ ssl \ cacert.pem

  1. No seu php.ini, coloque esta linha nesta seção ("c: \ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Reinicie seu servidor web / apache

  2. Problema resolvido!

(Referência: https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate )

Estrume
fonte
6
Esta mensagem está chegando devido à sua versão do PHP. Se for superior ao PHP 5.5, esse erro ocorre devido ao novo recurso do PHP 5.6. O PHP 5.6 verifica certificados se você estiver usando cURL.
UWU_SANDUN 28/03
9
Obrigado pela resposta! Embora eu recomendo usar o cacert.pem do curl-page oficial: curl.haxx.se/docs/caextract.html
dieBeiden
6
Só queria apontar para alguém que não pode fazer isso funcionar - usei barras curl.cainfo = "C:/cacert.pem"e também tive que reiniciar meu computador para fazê-lo funcionar. Apenas reiniciar o servidor web não foi suficiente. Espero que ajude:]
space_food_
1
e não se esqueça de descomentar curl.cainfo(facepalm)
Edmund Sulzanok
Trabalhou como um encanto! Obrigado
Jack
56

Atenção usuários do Wamp / Wordpress / windows. Eu tive esse problema por horas e nem a resposta correta estava fazendo isso por mim, porque eu estava editando o arquivo php.ini errado porque a pergunta foi respondida ao XAMPP e não para usuários do WAMP, mesmo que a pergunta fosse para o WAMP.

aqui está o que eu fiz

Faça o download do pacote de certificados.

Coloque dentro de C:\wamp64\bin\php\your php version\extras\ssl

Verifique se o arquivo mod_ssl.soestá dentro deC:\wamp64\bin\apache\apache(version)\modules

Ativar mod_sslno httpd.confinterior de diretório ApacheC:\wamp64\bin\apache\apache2.4.27\conf

Ativar php_openssl.dllno php.ini. Esteja ciente de que meu problema era que eu tinha dois arquivos php.ini e preciso fazer isso nos dois. O primeiro pode ser localizado dentro do seu ícone da barra de tarefas WAMP aqui.

insira a descrição da imagem aqui

e o outro está localizado em C:\wamp64\bin\php\php(Version)

encontre o local para os dois php.iniarquivos, encontre a linha curl.cainfo =e indique um caminho como este

curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"

Agora salve os arquivos e reinicie o servidor e você deve estar pronto

Rami Nour
fonte
É menos necessário que você faça o php.ini do que o que você pretende usar: se você estiver usando o apache como cliente SAPI, em seguida, altere o do diretório apache e / ou o do cliente dir se você planeja usar o php.exe como SAPI.
Fabien Haddadi
3
"Eu preciso fazer isso nos dois" é a nota principal. Obrigado
Jaroslav Klimčík
1
Isso funciona para o Laravel 5.5 com "guzzlehttp / guzzle": "^ 6.3". Servidor Wamp 3.1.3. Php 7.1 *
Deepesh Thapa
isso funcionou. Graças
user4906240
Obrigado por responder a wamp
altoids
46

Se você estiver usando o PHP 5.6 com o Guzzle, o Guzzle passou a usar as bibliotecas PHP de detecção automática de certificados em vez de seu processo ( ref ). O PHP descreve as mudanças aqui .

Descobrindo onde o PHP / Guzzle está procurando por certificados

Você pode despejar a localização do PHP usando:

 var_dump(openssl_get_cert_locations());

Obtendo um pacote de certificados

Para teste do OS X, você pode usar o homebrew para instalar o openssl brew install openssle, em seguida, usaropenssl.cafile=/usr/local/etc/openssl/cert.pem nas configurações do php.ini ou do Zend Server (em OpenSSL).

Um pacote de certificados também está disponível em curl / Mozilla no site do curl: https://curl.haxx.se/docs/caextract.html

Dizendo ao PHP onde estão os certificados

Depois de ter um pacote, coloque-o onde o PHP já está procurando (que você descobriu acima) ou atualize openssl.cafileno php.ini. (Geralmente, /etc/php.iniou /etc/php/7.0/cli/php.iniou /etc/php/php.inino Unix.)

Loren
fonte
3
SIM. Depois de ver muitas pessoas sugerirem a abordagem obviamente incorreta de fazer o downgrade por vários números de versão, essa é a abordagem correta. Eu segui o conselho de outras pessoas sobre o café, mas não tinha como testar por que ele ainda não carregava. Essa função openssl_get_cert_locations () realmente fez o trabalho de identificar meu problema. Obrigado!
Web and Flow
1
Obrigado por fornecer openssl_get_cert_locations, isso tornou a depuração muito mais fácil. Parece que o WAMP usa arquivo ini diferente para o apache php e para o console php. No meu caso, eu tive que adicionar openssl.cafile="c:/_/cacert.pem"para php baseado em console. Da última vez, ao usá-lo através do apache, eu precisava curl.cainfo="c:/_/cacert.pem"fazê-lo funcionar.
Psycho brm
16

O Guzzle, usado pelo cartalista / faixa , fará o seguinte para encontrar um arquivo de certificados adequado para verificar um certificado de servidor:

  1. Verifique se openssl.cafile está definido no seu arquivo php.ini.
  2. Verifique se curl.cainfo está definido no seu arquivo php.ini.
  3. Verifique se /etc/pki/tls/certs/ca-bundle.crt existe (Red Hat, CentOS, Fedora; fornecido pelo pacote ca-certificates)
  4. Verifique se /etc/ssl/certs/ca-certificates.crt existe (Ubuntu, Debian; fornecido pelo pacote ca-certificates)
  5. Verifique se /usr/local/share/certs/ca-root-nss.crt existe (FreeBSD; fornecido pelo pacote ca_root_nss)
  6. Verifique se /usr/local/etc/openssl/cert.pem(OS X; fornecido pelo homebrew)
  7. Verifique se C:\windows\system32\curl-ca-bundle.crtexiste (Windows)
  8. Verifique se C:\windows\curl-ca-bundle.crtexiste (Windows)

Você deseja certificar-se de que os valores para as duas primeiras configurações sejam definidos corretamente fazendo um teste simples:

echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";

Como alternativa, tente gravar o arquivo nos locais indicados por # 7 ou # 8.

Ja͢ck
fonte
13

Se você não conseguir alterar o php.ini, também poderá apontar para o arquivo cacert.pem a partir de código como este:

$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
mvandillen
fonte
8

O que eu fiz foi usar var_dump(openssl_get_cert_locations()); die;em qualquer script php, o que me deu as informações sobre os padrões que meu php local estava usando:

array (size=8)
  'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
  'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
  'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
  'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
  'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
  'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
  'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
  'ini_capath' => string '' (length=0)

Como você pode notar, eu configurei o ini_cafile ou a opção ini curl.cainfo. Mas no meu caso, o curl tentaria usar o "default_cert_file" que não existia.

Copiei o arquivo de https://curl.haxx.se/ca/cacert.pem no local para "default_cert_file" (c: /openssl-1.0.1c/ssl/cert.pem) e consegui obtê-lo trabalhar.

Esta foi a única solução para mim.

George Donev
fonte
Eu tenho um problema semelhante e minha localização é algo como c: /usr/local/ssl/cert.pem mas essa localização não existe, você sabe o que poderia ser, mais o mesmo projeto é usado pelo meu coluge na máquina mac poderia por isso, tentei de tudo, que está adicionando local de certificação no arquivo .ini, mas não funciona, parece que sua solução deve funcionar como faz sentido, mas não pode alterar esse local e não pode colocar certificado no local que não existe.
AbdulMueed
Você pode tentar criar as pastas e colocar o certificado no caminho especificado?
George Donev
7

Eu tive esse problema parecer inesperado um dia, quando um script do Guzzle (5) estava tentando se conectar a um host por SSL. Claro, eu poderia desativar a opção VERIFY no Guzzle / Curl, mas claramente esse não é o caminho correto.

Eu tentei de tudo listado aqui e em threads semelhantes, e finalmente fui para o terminal com openssl para testar o domínio com o qual estava tentando conectar:

openssl s_client -connect example.com:443 

... e recebeu as primeiras linhas indicando:

CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1 

... enquanto tudo funcionava bem ao tentar outros destinos (por exemplo: google.com, etc)

Isso me levou a entrar em contato com o domínio com o qual eu estava tentando conectar-me e, de fato, eles tiveram um problema em THE END END que havia surgido. Foi resolvido e meu script voltou a funcionar.

Então ... se você estiver arrancando os cabelos, dê uma chance ao openssl e veja se há algo com a resposta do local que você está tentando conectar. Talvez o problema não seja tão 'local', afinal de contas, às vezes.

Daydream Nation
fonte
6

Encontrei uma solução que funcionou para mim. Eu fiz o downgrade do último guzzle para a versão ~ 4.0 e funcionou.

No compositer.json, adicione "guzzlehttp / guzzle": "~ 4.0"

Espero que ajude alguém

Iruku Kagika
fonte
Isso também impedirá o uso de qualquer recurso da versão 5/6. Em vez disso, apenas defina verificar como falso em um array de parâmetros (terceiro parâmetro do método de solicitação): $ client-> request ('GET', '/', ['Verifique' => false]);
S ..
3

Certifique-se de abrir o php.iniarquivo diretamente pelo seu Windows Explorer. (no meu caso C:\DevPrograms\wamp64\bin\php\php5.6.25:).

Não use o atalho php.inino menu do ícone Wamp / Xamp na bandeja do sistema. Este atalho não funciona neste caso.

Então edite isso php.ini:

curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem" 

e

openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"

Após salvar, php.inivocê não precisa "Reiniciar todos os serviços" no ícone Wamp ou fechar / reabrir o CMD.

Quang Nguyen Tri
fonte
2

Você tentou..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Se você está consumindo uma fonte confiável, sem dúvida não precisa verificar o certificado SSL.

Mike Miller
fonte
2

Eu gastei muito tempo para descobrir esse problema para mim.

Eu tinha o PHP versão 5.5 e precisava atualizar para a 5.6.

Nas versões <5.6, o Guzzle usará seu próprio arquivo cacert.pem, mas nas versões superiores do PHP usará o arquivo cacert.pem do sistema.

Também baixei o arquivo aqui https://curl.haxx.se/docs/caextract.html e o configurei no php.ini.

Resposta encontrada no arquivo Guzzles StreamHandler.php https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437

        // PHP 5.6 or greater will find the system cert by default. When
        // < 5.6, use the Guzzle bundled cacert.
Marko Milivojevic
fonte
2

Todas as respostas estão corretas ; mas o mais importante é que você precisa encontrar o arquivo php.ini certo. marque este comando no cmd "php --ini" não é a resposta certa para encontrar o arquivo php.ini certo.

se você editar

curl.cainfo ="PATH/cacert.pem"

e verifique

var_dump(openssl_get_cert_locations()); 

então curl.cainfo deve ter um valor. caso contrário, isso não é o arquivo php.ini certo;

* Eu recomendo que você pesquise * .ini em wamp / bin ou xxamp / bin ou em qualquer servidor que você use, altere-os um por um e verifique-o. *

Mohsen Molaei
fonte
1

Acabei de experimentar esse mesmo problema com o framework Laravel 4 php, que usa o guzzlehttp/guzzlepacote compositor. Por alguma razão, o certificado SSL para mailgun parou de validar repentinamente e recebi a mesma mensagem de "erro 60".

Se, como eu, você estiver em uma hospedagem compartilhada sem acesso php.ini, as outras soluções não serão possíveis. De qualquer forma, o Guzzle tem este cliente inicializando o código que provavelmente anularia os php.iniefeitos:

// vendor/guzzlehttp/guzzle/src/Client.php
    $settings = [
        'allow_redirects' => true,
        'exceptions'      => true,
        'decode_content'  => true,
        'verify'          => __DIR__ . '/cacert.pem'
    ];

Aqui, o Guzzle força o uso de seu próprio arquivo cacert.pem interno, que provavelmente está agora desatualizado, em vez de usar o fornecido pelo ambiente do cURL . Alterar essa linha (pelo menos no Linux) configura o Guzzle para usar a lógica de verificação SSL padrão do cURL e corrigiu o meu problema:

        'verify'          => true

Você também pode definir isso falsese não se importar com a segurança da sua conexão SSL, mas essa não é uma boa solução.

Como os arquivos vendornão devem ser adulterados, uma solução melhor seria configurar o cliente Guzzle no uso, mas isso era muito difícil de fazer no Laravel 4.

Espero que isso economize para alguém mais algumas horas de depuração ...

Bernie
fonte
1

Pode ser um caso extremo, mas, no meu caso, o problema não era o cliente conf (eu já havia curl.cainfoconfigurado php.ini), mas o servidor remoto não está sendo configurado corretamente:

Não enviou nenhum certificado intermediário na cadeia. Não houve erro ao navegar no site usando o Chrome, mas com o PHP recebi o seguinte erro.

erro cURL 60

Depois de incluir os certificados intermediários na configuração do servidor da web remoto, ele funcionou.

Você pode usar este site para verificar a configuração SSL do seu servidor:

https://whatsmychaincert.com/

Tobias K.
fonte
1

quando corro 'var_dump(php_ini_loaded_file());' , recebo essa saída na minha página 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

e para obter o php para carregar meu arquivo cert, tive que editar o php.ini nesse caminho 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' e adicionar openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"onde havia baixado e colocar meu arquivo cert em https://curl.haxx.se/docs/caextract.html

estou no windows 10, usando drupal 8, wamp e php7.2.4

Nicholas
fonte
0

Eu tenho uma solução adequada para esse problema, vamos tentar entender a causa raiz desse problema. Esse problema ocorre quando os servidores remotos ssl não podem ser verificados usando certificados raiz no armazenamento de certificados do sistema ou o ssl remoto não está instalado junto com os certificados em cadeia. Se você possui um sistema linux com acesso root ssh, nesse caso, você pode tentar atualizar seu armazenamento de certificados com o comando abaixo:

update-ca-certificates

Se ainda assim, não funcionar, você precisará adicionar o certificado intermediário e raiz do servidor remoto em seu armazenamento de certificados. Você pode fazer o download de certificados raiz e intermediários e adicioná-los no diretório / usr / local / share / ca-certificates e, em seguida, executar o comando update-ca-certificates. Isso deve fazer o truque. Da mesma forma, no Windows, você pode pesquisar como adicionar certificados raiz e intermediário.

A outra maneira de resolver esse problema é pedir à equipe do servidor remoto para adicionar o certificado ssl como um pacote de certificação raiz do domínio, certificação intermediária e certificação raiz.

prasoon
fonte
-1

Como você está usando o Windows, acho que seu separador de caminho é '\' (e '/' no Linux). Tente usar a constante DIRECTORY_SEPARATOR. Seu código será mais portátil.

Experimentar:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');

EDIT: e escreva o caminho completo. Eu tive alguns problemas com caminhos relativos (talvez o curl seja executado em outro diretório base?)

C Würtz
fonte
1
Isso não faria diferença, porque as configurações reais de cURL estão fora de seu controle quando você usa essa biblioteca Stripe específica.
Ja͢ck
-1

se você usa o WAMP, também deve adicionar a linha de certificado no php.ini para Apache (além do arquivo php.ini padrão):

[curl]
curl.cainfo = C:\your_location\cacert.pem

funciona para php5.3 +

prumo
fonte
Sim! Cuidado para editar os arquivos apache e php version php.ini. Para usuários do WAMP, esta resposta foi a única a resolver o meu problema: stackoverflow.com/questions/28858351/…
MavBzh: