Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python requests gives me "bad handshake" error

Using Python requests like this

import requests;
requests.get('https://internal.site.no')

gives me an error many have had;

SSLError: ("bad handshake: Error([('SSL routines', 'SSL23_GET_SERVER_HELLO', 'sslv3 alert handshake failure')],)",)

however, none of the missing package they suggest works. Even setting verify=False gives me the same error. Curl gives me no error trying to access the same site.

Versions:

  • Alpine 3.4
  • requests 2.12.1 (it works in 2.11.1)
  • OpenSSL 1.0.2j 26 sep 2016
like image 441
xeor Avatar asked Nov 22 '16 12:11

xeor


1 Answers

The most likely error is that requests and the server are not able to negotiate a cipher to use.

Check what curl uses;

curl --verbose https://internal.site.no/

It will give you a lot of output, but the one you are looking for is something like SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256.

Looking at the diff from 2.11.1 to 2.12.0 of requests, shows a new version of urllib3 (to version 1.19). Maybe it's the removal of 3des that bites you here?

If you check your curl --verbose ... output used cipher against this usefull list of cipher name mapping. You can try adding the openssl name of the name to what requests accept, example (you can do this in the beginning of your app/script):

import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':ADH-AES128-SHA256'

if curl shows you that it is using TLS_DH_anon_WITH_AES_128_CBC_SHA256 (as an example).

Another handy tip is to use the nmap script ssl-enum-ciphers, like this:

nmap --script ssl-enum-ciphers -p 443 internal.site.no

to get a list of what it finds as supported ciphers (note, script might be noisy)...

like image 96
xeor Avatar answered Sep 18 '22 00:09

xeor