file_get_contents(): SSL operation failed with code 1, Failed to enable crypto

前端 未结 16 1786
情歌与酒
情歌与酒 2020-11-22 04:31

I’ve been trying to access this particular REST service from a PHP page I’ve created on our server. I narrowed the problem down to these two lines. So my PHP page looks li

相关标签:
16条回答
  • 2020-11-22 04:35

    You basically have to set the environment variable SSL_CERT_FILE to the path of the PEM file of the ssl-certificate downloaded from the following link : http://curl.haxx.se/ca/cacert.pem.

    It took me a lot of time to figure this out.

    0 讨论(0)
  • 2020-11-22 04:39

    following below steps will fix this issue,

    1. Download the CA Certificate from this link: https://curl.haxx.se/ca/cacert.pem
    2. Find and open php.ini
    3. Look for curl.cainfo and paste the absolute path where you have download the Certificate. curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
    4. Restart WAMP/XAMPP (apache server).
    5. It works!

    hope that helps !!

    0 讨论(0)
  • 2020-11-22 04:42

    Had the same error with PHP 7 on XAMPP and OSX.

    The above mentioned answer in https://stackoverflow.com/ is good, but it did not completely solve the problem for me. I had to provide the complete certificate chain to make file_get_contents() work again. That's how I did it:

    Get root / intermediate certificate

    First of all I had to figure out what's the root and the intermediate certificate.

    The most convenient way is maybe an online cert-tool like the ssl-shopper

    There I found three certificates, one server-certificate and two chain-certificates (one is the root, the other one apparantly the intermediate).

    All I need to do is just search the internet for both of them. In my case, this is the root:

    thawte DV SSL SHA256 CA

    And it leads to his url thawte.com. So I just put this cert into a textfile and did the same for the intermediate. Done.

    Get the host certificate

    Next thing I had to to is to download my server cert. On Linux or OS X it can be done with openssl:

    openssl s_client -showcerts -connect whatsyoururl.de:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/whatsyoururl.de.cert
    

    Now bring them all together

    Now just merge all of them into one file. (Maybe it's good to just put them into one folder, I just merged them into one file). You can do it like this:

    cat /tmp/thawteRoot.crt > /tmp/chain.crt
    cat /tmp/thawteIntermediate.crt >> /tmp/chain.crt
    cat /tmp/tmp/whatsyoururl.de.cert >> /tmp/chain.crt
    

    tell PHP where to find the chain

    There is this handy function openssl_get_cert_locations() that'll tell you, where PHP is looking for cert files. And there is this parameter, that will tell file_get_contents() where to look for cert files. Maybe both ways will work. I preferred the parameter way. (Compared to the solution mentioned above).

    So this is now my PHP-Code

    $arrContextOptions=array(
        "ssl"=>array(
            "cafile" => "/Applications/XAMPP/xamppfiles/share/openssl/certs/chain.pem",
            "verify_peer"=> true,
            "verify_peer_name"=> true,
        ),
    );
    
    $response = file_get_contents($myHttpsURL, 0, stream_context_create($arrContextOptions));
    

    That's all. file_get_contents() is working again. Without CURL and hopefully without security flaws.

    0 讨论(0)
  • 2020-11-22 04:47

    This was an enormously helpful link to find:

    http://php.net/manual/en/migration56.openssl.php

    An official document describing the changes made to open ssl in PHP 5.6 From here I learned of one more parameter I should have set to false: "verify_peer_name"=>false

    Note: This has very significant security implications. Disabling verification potentially permits a MITM attacker to use an invalid certificate to eavesdrop on the requests. While it may be useful to do this in local development, other approaches should be used in production.

    So my working code looks like this:

    <?php
    $arrContextOptions=array(
        "ssl"=>array(
            "verify_peer"=>false,
            "verify_peer_name"=>false,
        ),
    );  
    
    $response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));
    
    echo $response; ?>
    
    0 讨论(0)
  • 2020-11-22 04:48

    If your PHP version is 5, try installing cURL by typing the following command in the terminal:

    sudo apt-get install php5-curl
    
    0 讨论(0)
  • 2020-11-22 04:49

    Reason for this error is that PHP does not have a list of trusted certificate authorities.

    PHP 5.6 and later try to load the CAs trusted by the system automatically. Issues with that can be fixed. See http://php.net/manual/en/migration56.openssl.php for more information.

    PHP 5.5 and earlier are really hard to setup correctly since you manually have to specify the CA bundle in each request context, a thing you do not want to sprinkle around your code. So I decided for my code that for PHP versions < 5.6, SSL verification simply gets disabled:

    $req = new HTTP_Request2($url);
    if (version_compare(PHP_VERSION, '5.6.0', '<')) {
        //correct ssl validation on php 5.5 is a pain, so disable
        $req->setConfig('ssl_verify_host', false);
        $req->setConfig('ssl_verify_peer', false);
    }
    
    0 讨论(0)
提交回复
热议问题