Python SSL socket can't connect to self-signed certificate

6.9k Views Asked by At

I need to connect SSL socket to SSL server. The following script fails if the server's certificate is self-signed. But it works if the server's certificate is signed. Can you help me how can I successfully connect to server's with self-signed certificates?

import StringIO
import csv     #for csv
from M2Crypto.Err import SSLError
import ssl
import socket
import pprint
import M2Crypto
from M2Crypto import X509, RSA

from datetime import datetime
import MySQLdb

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_NONE

host='209.18.59.115'
print 'host is: ', host
port=443

#creating ssl socket
ssock = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)

#ssl connection
try:
    ssock.connect((host, port))
except socket.error: #if tls connection is not possible, print error message, then go to next host.
    print "Faile connection with: " + host

EDIT: The output I get is what in the exception statement:

host is:  209.18.59.115
Faile connection with: 209.18.59.115 

EDIT2: The traceback is:

Traceback (most recent call last):
  File "C:/Users/xxx/PycharmProjects/tlsScan/test2.py", line 28, in <module>
    ssock.connect((host, port))
  File "C:\Python27\lib\ssl.py", line 824, in connect
    self._real_connect(addr, False)
  File "C:\Python27\lib\ssl.py", line 815, in _real_connect
    self.do_handshake()
  File "C:\Python27\lib\ssl.py", line 788, in do_handshake
Faile connection with: 209.18.59.115
    self._sslobj.do_handshake()
SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:581)
None
1

There are 1 best solutions below

0
On

The problem was in this line: context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)

It happened that the server that I was trying to connect to does not support TLSv1.2. When I changed the line to the following, it works: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) #we choose SSLv23 because it is compatible with all versions except SSLv2.

The TLS client/server compatibility table (source: https://docs.python.org/2/library/ssl.html): Here’s a table showing which versions in a client (down the side) can connect to which versions in a server (along the top):

client / server     SSLv2   SSLv3   SSLv23  TLSv1   TLSv1.1     TLSv1.2
SSLv2                yes     no       yes    no        no         no
SSLv3                no      yes      yes    no        no         no
SSLv23               no      yes      yes    yes       yes        yes
TLSv1                no      no       yes    yes       no         no
TLSv1.1              no      no       yes    no        yes        no
TLSv1.2              no      no       yes    no        no         yes

Because TLSv23 is compatible with most of the server's supported versions, I chose it and it worked.