SSL peer certificate or SSH remote key was not OK

2019-04-20 18:03发布

问题:

I'm testing an API that uses curl_exec php function and a CA certificate but something is going wrong and I'm a little lost.

I have configured SSL on my apache VirtualHost and looks ok ( opening https:://[myVHost]... works ).

However the API curl call give me back this message:

  • SSL peer certificate or SSH remote key was not OK

I'm not very experienced with SSL so I have few ideas about the cause of that.

UPDATE:

This is the code I'm using in my cURL request, I have commented 2 lines and changes their value (look at 'TODO' line ) and in this way it is working, however this is just a work arround ...

$opts[CURLOPT_URL] = $url;
    $opts[CURLOPT_RETURNTRANSFER] = true;
    $opts[CURLOPT_CONNECTTIMEOUT] = 50;
    $opts[CURLOPT_TIMEOUT] = 100;
    $headers = array(
        'Accept: application/json',
        "User-Agent: APIXXX-PHP-Client");
    $opts[CURLOPT_HTTPHEADER] = $headers;
    $opts[CURLOPT_USERPWD] = $env->getApiKey() . ':';
    if (certificatePresent()) {

        //  $opts[CURLOPT_SSL_VERIFYPEER] = true;
        //  $opts[CURLOPT_SSL_VERIFYHOST] = 2;

        // TODO: SET IT BACK
        $opts[CURLOPT_SSL_VERIFYPEER] = 0;
        $opts[CURLOPT_SSL_VERIFYHOST] = 0;

        $opts[CURLOPT_CAINFO] = $path

      }

    curl_setopt_array($curl, $opts);

    $response = curl_exec($curl);

回答1:

You are probably using self-signed SSL certifiacate, which will not pass when the CURLOPT_SSL_VERIFYPEER options is set.

There are two solutions:

  1. Buy valid SSL certificate.
  2. Disable SSL verification in Curl. (add --insecure option)

If you disable verification, you can't be sure if you are really communicating with your host. So it depends on level of security you need.



回答2:

Although I am answering an old post, I think it will help the new viewers-

You can check the problem by adding

$opts[CURLOPT_VERBOSE] = 1

For self signed certificate your client may connect with the server using IP address, because the host name is not available in DNS cache. In that case the COMMON NAME(CN) of your server certificate needs to match with the Server IP (put IP address as common name when generating the server certificate). When you do it correctly, you can see this message:

common name: 192.168.0.1 (matched)

Here 192.168.0.1 is an example.



回答3:

Beside CURLOPT_SSL_VERIFYPEER there are two other settings which might be changed to false/0:

CURLOPT_SSL_VERIFYHOST
CURLOPT_SSL_VERIFYSTATUS

Beware that you should fix your SSL certificates & settings instead of disable security!



回答4:

You're right to want to enable SSL_VERIFYPEER if you are worried about man-in-the-middle attacks.

Is your $path set to point to the certificate (or certificate bundle) provided by the API owner? Is that certificate readable by the web server user? If so, have you verified that the certificate(s) is the same as when you visit the https address manually in a browser and inspect the certificate?

If you can't get it to work, and the API you are connecting to has a SSL certificate that works in your normal browser without warnings, you should be able to set $path to your CA root bundle on your server.



回答5:

You can build a valid SSL certificate and ensure that it is stored in the trusted folder.

Valid SSL certificate can be created by including the following command in the developer command prompt of VS2012. (This can be obtained by typing developer in the start)

The following command creates a self-signed certificate that can be used to test a web application that uses Secure Sockets Layer (SSL) on a web server whose URL is www.example.com. The OID defined by the -eku option identifies that certificate as an SSL server certificate. The certificate is stored in the my store and is available at the machine (rather than user) level. The certificate's private key is exportable, and the certificate is valid from May 10, 2010 through December 22, 2011.

Makecert -r -pe -n CN="www.example.com" -b 05/10/2010 -e 12/22/2011 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

For more on how to create the SSL certificate

Now make sure that this certificate is trusted, this can be done by typing CERTMGR in the cmd..

now the cert created is in the PERSONAL folder.. copy it and paste it to the TRUSTED PEOPLE FOLDER.

This should do the trick. Let me know if that doesn't work.



回答6:

I had the same issue. I follow the instruction here: http://siteber.com/download-failed-ssl-peer-certificate-or-ssh-remote-key-was-not-ok/ and it fixed mine.

basically I went to /etc/resolv.conf

and Replace any

OpenDNS server:

208.67.222.222

208.67.220.220

With

Google’s public DNS servers:

nameserver 8.8.8.8 nameserver 8.8.4.4