Skip to Content

Fixing SSLV3_ALERT_HANDSHAKE_FAILURE in Python’s requests Module

The SSL: SSLV3_ALERT_HANDSHAKE_FAILURE error in Python’s requests module typically occurs due to a failure in the SSL/TLS handshake process.

This can be caused by various issues, including incompatible SSL/TLS versions, cipher suites, or SSL certificate problems.

Using OpenSSL to Diagnose SSL Issues

The OpenSSL command-line tool can be used to manually initiate an SSL handshake with the server, which can help determine if the issue is network-related or due to software configuration.

The command will show detailed information about the SSL handshake process and can help pinpoint the stage where the failure occurs.

How to Use OpenSSL for Diagnosis

  1. Open a terminal or command prompt.
  2. Run the OpenSSL command to initiate an SSL handshake:
    openssl s_client -connect hostname:port -tls1_2

    Replace hostname and port with the server’s details. Try different SSL/TLS versions as needed.

  3. Analyze the output for error messages or warnings, cipher suite compatibility, and certificate details.

Interpreting the Results

If OpenSSL successfully establishes a connection but the Python script does not, the issue is likely within the Python environment or script.

If OpenSSL also fails, the problem might be network-related or due to the server’s SSL configuration.

Steps to Fix SSLV3_ALERT_HANDSHAKE_FAILURE

Here are steps to resolve this issue:

Update Python and requests Module

  • Ensure the latest versions of Python and the requests module are in use. Newer versions of Python often include security patches that fix vulnerabilities found in older versions. By updating, you protect your applications from known security risks.
  • Update Python from the official Python website.
  • Update requests module using pip:
pip install --upgrade requests

Install/Update pyOpenSSL, cryptography, and ndg-httpsclient

  • These packages enhance SSL/TLS support in Python.
  • Install or update them using pip:
pip install --upgrade pyOpenSSL cryptography ndg-httpsclient

Check Server SSL Configuration

Use tools like SSL Labs’ SSL Test to examine the server’s SSL setup. SSL Labs’ SSL Test is a free online service that performs a deep analysis of the configuration of any web server on the public internet. 

It assesses the server’s SSL/TLS configuration by testing its public URL. The analysis includes checking supported protocols, cipher suites, key exchange methods, and certificate details.

Ensure the server supports modern SSL/TLS protocols and cipher suites.

Force Specific SSL Version or Cipher Suite (If Appropriate)

Forcing Python’s requests library to use a specific SSL version or cipher suite can sometimes be necessary, especially when interacting with older servers or in environments with specific security requirements.

Example:

import requests
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

# Create an SSL context
ctx = create_urllib3_context(ssl_version='your_ssl_version', ciphers='your_cipher_suite')

# Use the context in a session
s = requests.Session()
s.mount('https://', SSLAdapter(ssl_context=ctx))
response = s.get('https://example.com')

It’s generally safer to rely on the requests library’s default settings, as they are configured to choose the most secure and compatible options.
Forcing specific SSL/TLS settings should be a last resort, used only when necessary and understanding the risks.

Check Client Certificate (If Using)

When making secure requests to a server, especially in enterprise or business-to-business scenarios, you might be required to use a client certificate.

This is a form of mutual authentication where both the client and the server authenticate each other. 

Unlike a typical SSL/TLS handshake where only the server is authenticated by the client, client certificates are used to authenticate the client to the server.

This adds an extra layer of security by ensuring that only authorized clients can communicate with the server.

Ensure the client certificate is correctly specified and valid.

Example:

response = requests.get('https://example.com', cert=('/path/client.cert', '/path/client.key'))

This code snippet tells requests to present the specified client certificate and key when establishing an SSL/TLS connection to https://example.com.

Verify System’s Root Certificates

Keeping the system’s root certificates updated is crucial for maintaining secure communications and avoiding SSL/TLS handshake failures.

Root certificates are fundamental in the SSL/TLS protocol, as they establish the trustworthiness of SSL certificates presented by websites.

Root certificates are the topmost certificates in the SSL/TLS certificate chain. They are issued by trusted Certificate Authorities (CAs).

When you access a secure website (HTTPS), your browser or client software checks the website’s SSL certificate against these root certificates to verify its authenticity.

If the website’s certificate is not trusted by any root certificate on your system, the SSL/TLS handshake fails, leading to errors like SSLV3_ALERT_HANDSHAKE_FAILURE.

Conclusion

  • Be careful with changing SSL settings, especially in production environments. Prioritize security and compatibility.
  • Avoid disabling SSL verification (verify=False) in production to prevent security vulnerabilities.