fockopen: Failed to enable crypto

12,744

After much head bashing, I finally discovered the cause.

PHP 5.6 implemented a default set of support ciphers, which removed support for older more vulnerable ones. http://php.net/manual/en/migration56.openssl.php

The default ciphers used by PHP have been updated to a more secure list based on the » Mozilla cipher recommendations, with two additional exclusions: anonymous Diffie-Hellman ciphers, and RC4. The domain I was attempting to connected currently supports TLSv1/SSLv3, Cipher RC4-MD5

Do work around the issue I switched to stream_socket_client instead of fsockopen. Added RC4-MD5 to stream cipher support in the context:

$context = stream_context_create(['ssl' => [
  'ciphers' => 'RC4-MD5'
]]);

$socket = stream_socket_client('ssl://'.$host.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
Share:
12,744
user3545769
Author by

user3545769

Updated on June 04, 2022

Comments

  • user3545769
    user3545769 almost 2 years

    Similar questions have been answered before, but I haven't been able to solve this particular case.

    On a PHP 5.6+ machine when I try to use fsockopen on a particular domain I receive the following (not the real domain):

    $ php -r "var_dump(fsockopen(\"ssl://www.domain.net\", 9085, \$errnum, \$errstr, 5));"
    PHP Warning:  fsockopen(): Failed to enable crypto in Command line code on line 1
    PHP Warning:  fsockopen(): unable to connect to ssl://www.domain.net:9085 (Unknown error) in Command line code on line 1
    bool(false)
    

    This works fine on PHP 5.5, which points to it being by the change in 5.6 dealing with the way fsockopen verifies ssl certificates.

    Other connections can be made without issue:

    $ php -r "var_dump(fsockopen(\"ssl://www.google.com\", 443, \$errnum, \$errstr, 5));"
    resource(4) of type (stream)
    

    Based on other suggestions I've checked the default cert file

    $ php -r "print_r(openssl_get_cert_locations());"
    Array
    (
        [default_cert_file] => /usr/lib/ssl/cert.pem
        [default_cert_file_env] => SSL_CERT_FILE
        [default_cert_dir] => /usr/lib/ssl/certs
        [default_cert_dir_env] => SSL_CERT_DIR
        [default_private_dir] => /usr/lib/ssl/private
        [default_default_cert_area] => /usr/lib/ssl
        [ini_cafile] =>
        [ini_capath] =>
    )
    

    The file /usr/lib/ssl/cert.pem was originally missing, I download the ca bundle from curl and renamed it to match. Still no luck.

    I'm not receiving any additional information indicating that verifying the certificate fails. Are there any other ways to debug the issue?