Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to choose the Transport Layer Security protocol in urllib2

I want to choose the transport layer protocol used for opening https links using urllib2.urlopen() in Python 2.7

Similar to what we can do using openssl utility:

openssl s_client -connect www.google.com:443 -ssl2
openssl s_client -connect www.google.com:443 -ssl3
openssl s_client -connect www.google.com:443 -tls1

The motive is to not use ssl2 protocol that leads to handshake problems in most of the servers. urllib2 seems to use SSLv23 protocol that uses SSLv2 or SSLv3 with some kind of fall of mechanism. There are cases where this leads to handshake issues

like image 401
attaboyabhipro Avatar asked Mar 26 '14 10:03

attaboyabhipro


People also ask

What is TLS over TCP?

The Transport Layer Security (TLS) protocol adds a layer of security on top of the TCP/IP transport protocols. TLS uses both symmetric encryption and public key encryption for securely sending private data, and adds additional security features, such as authentication and message tampering detection.

Who uses TLS?

Both TLS and SSL are widely used in web browsers, email, messaging apps, and other applications—although TLS has generally displaced SSL in newer systems. Generally, TLS offers stronger encryption algorithms for authentication and supports pre-shared keys and secure remote passwords.

What are the steps in the Transport Layer security TLS handshake?

The TLS Handshake Protocol involves the following steps: The client sends a "Client hello" message to the server, along with the client's random value and supported cipher suites. The server responds by sending a "Server hello" message to the client, along with the server's random value.


1 Answers

Update: Since Python 2.7.9 you could pass SSLContext that specifies TLS protocol to urlopen() function:

import ssl
import urllib2

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
# other settings (see ssl.create_default_context() implementation)
urllib2.urlopen('https://example.com', context=context).close()

old answer:

httplib.HTTPSConnection and urllib2.HTTPSHandler do not allow to change ssl version but ssl.wrap_socket() does.

You could define your own HTTPSHandler that would allow you to pass arbitrary arguments to ssl.wrap_socket() e.g., urllib2_ssl.py:

>>> import ssl
>>> import urllib2
>>> import urllib2_ssl # https://gist.github.com/zed/1347055
>>> opener = urllib2.build_opener(urllib2_ssl.HTTPSHandler(
...     ssl_version=ssl.PROTOCOL_TLSv1, #XXX you need to modify urllib2_ssl
...     ca_certs='cacert.pem')) # http://curl.haxx.se/ca/cacert.pem.bz2
>>> opener.open('https://example.com/').read()
like image 56
jfs Avatar answered Oct 21 '22 05:10

jfs