How to fix curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s)

65,934

Solution 1

The server supports only ECC ciphers (ECDHE-*). The version of curl is built with the NSS library on Redhat/CentOS. There is a bug report that Redhat/CentOS overrides the curl settings and disables ECC ciphers by default. Because there are thus no ECC ciphers offered by the client but only ECC ciphers are supported by the server the connection will fail.

You might try to explicitly give the cipher, i.e.

curl --ciphers ecdhe_rsa_aes_128_gcm_sha_256 ...

Note that upgrading OpenSSL would not help because curl is not built with the OpenSSL backend. Also it does not help to disable certificate validation (bad idea anyway) or to change the root CA's since the problem is not related to certificate validation at all.

Trying to explicitly give the cipher with --ciphers ecdhe_ecdsa_aes_128_sha as the cipher to solve the problem goes into the right direction but will not help in this case, because this is not one of the ciphers supported by the servers. The server supports only various ECDHE-RSA-* ciphers but not ECDHE-ECDSA-* ciphers. See SSLLabs for details.

Solution 2

If you're on CentOS 7 and are getting these errors while using yum, updating nss nss-util nss-sysinit nss-tools will fix it.

Solution 3

On Centos 7 or above upgrading the curl to the latest version i.e. 7.29.* fixed the issue for me.

Share:
65,934
Admin
Author by

Admin

Updated on January 17, 2020

Comments

  • Admin
    Admin over 4 years

    I am trying to access and download some .torrent files from https://torrage.com using php curl. But nothing happens , curl_error($ch) gives

    $ch = curl_init ('https://torrage.com/torrent/640FE84C613C17F663551D218689A64E8AEBEABE.torrent');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_VERBOSE,true);
    $data = curl_exec($ch);
    $error = curl_error($ch);
    curl_close ($ch);
    echo $error;
    

    this gives.

    Cannot communicate securely with peer: no common encryption algorithm(s).
    

    If I try from shell like this

    [root@prod1 yum.repos.d]# curl -I https://torrage.com
    curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
    

    in verbose mode

    [root@prod1 yum.repos.d]# curl -v https://torrage.com
    * Rebuilt URL to: https://torrage.com/
    *   Trying 81.17.30.48...
    * Connected to torrage.com (81.17.30.48) port 443 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * NSS error -12286 (SSL_ERROR_NO_CYPHER_OVERLAP)
    * Cannot communicate securely with peer: no common encryption algorithm(s).
    * Closing connection 0
    curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
    

    system info centos 7. x86_64

    [root@prod1 yum.repos.d]# uname -a
    Linux prod1.localdomain 3.10.0-229.4.2.el7.x86_64 #1 SMP Wed May 13 10:06:09 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
    

    curl version

    [root@prod1 yum.repos.d]# curl -V
    curl 7.29.0 (x86_64-redhat-linux-gnu)
    

    openssl , already patched.

    [root@prod1 yum.repos.d]# openssl version -a
    OpenSSL 1.0.1e-fips 11 Feb 2013
    built on: Mon Jun 15 18:39:20 UTC 2015
    platform: linux-x86_64
    options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
    compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
    OPENSSLDIR: "/etc/pki/tls"
    engines:  dynamic
    

    verifying openssl patched or not.

    [root@prod1 yum.repos.d]# rpm -q --changelog openssl | grep CVE-2014-0224
    - fix CVE-2014-0224 fix that broke EAP-FAST session resumption support
    - fix CVE-2014-0224 - SSL/TLS MITM vulnerability
    

    What i have tried :

    1) i have tried using HTTP insted of HTTPS, but the site forces to use HTTPS. e.g.

    [root@prod1 yum.repos.d]# curl -I http://torrage.com
    HTTP/1.1 301 Moved Permanently
    Server: nginx/1.9.0
    Date: Mon, 29 Jun 2015 04:13:17 GMT
    Content-Type: text/html
    Content-Length: 184
    Connection: keep-alive
    Location: https://torrage.com/
    

    2) updating ca-bundle.crt

    cp /etc/pki/tls/certs/ca-bundle.crt /root/backup/
    curl http://curl.haxx.se/ca/cacert.pem -o /etc/pki/tls/certs/ca-bundle.crt
    

    3) Updating Curl to latest version 7.43.0

    nano /etc/yum.repos.d/city-fan-for-curl.repo
    

    with this repo.

    [CityFanforCurl]
    name=City Fan Repo
    baseurl=http://www.city-fan.org/ftp/contrib/yum-repo/rhel7/x86_64/
    enabled=0
    gpgcheck=0
    

    and then doing

    yum update curl --enablerepo=CityFanforCurl
    

    then verifying curl version

    [root@prod1 yum.repos.d]# curl -V
    curl 7.43.0 (x86_64-redhat-linux-gnu) libcurl/7.43.0 NSS/3.18 Basic ECC zlib/1.2.7 libidn/1.28 libssh2/1.6.0
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
    Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets Metalink
    

    4) i have tried this to check whether my curl is outdated or not.

    reference: https://unix.stackexchange.com/questions/162816/disable-sslv3-in-curl

    [root@prod1 yum.repos.d]# curl -1IsS --ciphers ecdhe_ecdsa_aes_128_sha https://sslspdy.com
    HTTP/1.1 200 OK
    Server: nginx centminmod
    Content-Type: text/html; charset=utf-8
    Connection: close
    Vary: Accept-Encoding
    Strict-Transport-Security: max-age=31536000; includeSubdomains
    Date: Mon, 12 Jan 1970 23:00:11 GMT
    X-Page-Speed: ngx_pagespeed
    Cache-Control: max-age=0, no-cache
    

    How can i fix the issue ? and download files from Torrage.com using PHP Curl ?

    *I cant use file_get_contents as i am using curl_multi for simultaneous downloads.


    Update 1:

    As suggested by steffen-ullrich

    [root@prod1 randoadmin]# curl --ciphers ecdhe_rsa_aes_128_gcm_sha_256 -I https://torrage.com
    HTTP/1.1 200 OK
    Server: nginx/1.9.0
    Date: Mon, 29 Jun 2015 05:54:17 GMT
    Content-Type: text/html; charset=UTF-8
    Connection: keep-alive
    Expires: Mon, 26 Jul 1997 05:00:00 GMT
    Last-Modified: Mon, 29 Jun 2015 05:50:40 GMT
    Cache-Control: no-store, no-cache, must-revalidate
    Cache-Control: post-check=0, pre-check=0
    Pragma: no-cache
    Vary: Accept-Encoding, Accept-Encoding
    Strict-Transport-Security: max-age=31536000
    X-Frame-Options: DENY
    X-Content-Type-Options: nosniff
    

    but thats with shell how can i implement it with PHP-curl ?

    Update 2:

    i have modified code and defined cipher to use while using curl like this.

    $ch = curl_init ('https://torrage.com/torrent/640FE84C613C17F663551D218689A64E8AEBEABE.torrent');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ecdhe_rsa_aes_128_gcm_sha_256');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_VERBOSE,true);
    $data = curl_exec($ch);
    $error = curl_error($ch);
    curl_close ($ch);
    echo $error;
    echo $data ;
    

    Its working great. Issue solved many thanks to steffen-ullrich .

  • Admin
    Admin almost 9 years
    Thanks , for your input, its very heavy for me understand the ciphers , but i am learning, so far its working on shell, but how can i define cipher in php curl request ? thanks
  • Steffen Ullrich
    Steffen Ullrich almost 9 years
    @AMB: If you use the documentation at php.net/manual/en/function.curl-setopt.php and you will find the CURLOPT_SSL_CIPHER_LIST setting.
  • Admin
    Admin almost 9 years
    thanks , fixed code and its working like charm. i really appreciate it.,
  • vrtech77
    vrtech77 over 8 years
    for me curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ecdhe_rsa_aes_128_gcm_sha_256'); worked as it was a different torrent site.
  • redDevil
    redDevil almost 8 years
    After about 2 hours of debugging, setting multiple options for curl in my php page, you saved me. Thank you! If you are on a VPS and a curl command line call gives curl: (35) Cannot communicate securely with peer error, try above yum update, should help. command is : yum update nss nss-util nss-sysinit nss-tools
  • Jared Smith
    Jared Smith almost 8 years
    While this might be valuable info, it is not an answer.
  • Walt
    Walt almost 8 years
    The answer is: when nothing of the above works, check Curl version and update it. Had this valuable info been here the day before yesterday, it would have saved me two days of my life.
  • Manu
    Manu over 5 years
    It has worked for me after trying above ciphers and nss update suggestions.
  • bonh
    bonh almost 5 years
    This is a good suggestion, but in general the cipher used by your test site (youtube.com) might not be supported by the target site.