SSLV3_ALERT_HANDSHAKE_FAILURE in 2.6.2

```
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:600)
```

Started happening consistently after upgrading to Requests 2.6.2. Tested in both Yosemite and Ubuntu 14.04. Python 3.4.3.

Downgrading to Requests 2.6.0 solves the issue.


@Nelluk Can you provide more information on what causes this? Which server are you accessing, etc?

At the moment, the most likely change in that delta is the fact that we slightly changed our default SSL cipher list:

```
- ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
+ ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:!eNULL:!MD5
```

It's possible this is causing a problem, though it's tricky to see how: knowing what server you're contacting would help me diagnose in that regard.


Some experimentation in IRC shows this to be transient: sometimes it works, sometimes it doesn't, but it only ever fails to work in 2.6.2: it always works in 2.6.0.

This suggests one of the two servers at this host has a bad cipher configuration that we don't like. Looking at the successful handshake, from 2.6.0 we negotiate TLS_RSA_WITH_RC4_128_SHA (a truly terrible cipher), whereas from 2.6.2 we negotiate TLS_RSA_WITH_3DES_EDE_CBC_SHA (still not great, but a bit better).

Looks like the change to make is to pass a custom cipher set.


That said, it looks like RC4 should have been forbidden in the old codebase: I assume I'm missing a change where we now always override the stdlib cipher suite.


Before we conditionally used our own cipher suite. Now we unconditionally use it.


Right, that'll do it. So, we probably broke some stuff there: we should at the very least blog about how to change the cipher suite.

Cory

> On 26 Apr 2015, at 14:48, Ian Cordasco notifications@github.com wrote:
> 
> Before we conditionally used our own cipher suite. Now we unconditionally use it.
> 
> —
> Reply to this email directly or view it on GitHub.


Any follow up on that blog? Im hitting this issue in Python 2.7.9. How do we go about putting in a custom cipher suite?

[Edit] Im using requests 2.7.0 and downgrading to 2.6.0 also works for me.


For the moment, setting a custom cipher suite is done by changing `requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS` (or `requests.packages.urllib3.contrib.pyopenssl.DEFAULT_CIPHER_LIST` if you're using PyOpenSSL: best to change both).

I'm holding off on a more formal bit of documentation for now because ideally we'll land a 'custom SSL context' patch into urllib3 that will make this API way better.


If I am writing an update for this issue, should I use Python 2.7.8 or should I use Python 3?


Ideally, both. =)


Does the above PR fix this issue or are does it fix something else related to this issue?


I have no idea: I strongly suggest that you ask in the PR itself. It was never opened against the requests project. 


Hah, sorry, I read too fast, should have looked at the proejct it was referenced in, I thought it was this one. My bad.


I'm getting this with v2.12.4, only the line number is different:
`requests.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:749)`

EDIT
Changing the value `requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS` to the old value fixes the issue for me.

In 2.12.4 there is no `requests.packages.urllib3.contrib.pyopenssl.DEFAULT_CIPHER_LIST` - do you mean ` requests.packages.urllib3.contrib.pyopenssl.ssl._DEFAULT_CIPHERS`?

> Lukasa commented on 14 May 2015
> 
> For the moment, setting a custom cipher suite is done by changing 
> requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS (or 
> requests.packages.urllib3.contrib.pyopenssl.DEFAULT_CIPHER_LIST if
> you're using PyOpenSSL: best to change both).
>


No, there is now only one cipher list in urllib3: no need to change both.

Same problem here with versions `2.12.1` and `2.13.0`.

Hotfixed with this:

    import requests
    requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = \
            requests.packages.urllib3.contrib.pyopenssl.ssl._DEFAULT_CIPHERS
    response = requests.get(...)

I could get this to work only with:

```
requests[security]==2.7.0  # not 2.18.x
cryptography==1.9   # not 2.0
```

@michi88 Please open a new bug report with a complete description of your problem. 

The versions in this issue are all ancient, if this issue is still occurring please reopen a new issue with supported versions of Requests+Python.