6

I'm stuck with an ssl error!?

Upgraded from 19.10 to 20.04 and get this error:

ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)

It is raised by a python script calling a rest API to oanda.com.

Connecting to the service with Postman or OANDA's java app both work without fault. Also, have the python script running on an RPi OK, after one change, see below!

20.04 - OpenSSL 1.1.1f 31 Mar 2020

RPi - OpenSSL 1.1.1d 10 Sep 2019

The problem was also on the RPi and research found a couple of suggestions to change the setting CipherString = DEFAULT@SECLEVEL=2 to CipherString = DEFAULT@SECLEVEL=1 in the /etc/ssl/openssl.cnf file. This worked on the RPi but did not work on Ubuntu 20.04.

Any ideas on how to resolve this?


Error report:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 996, in _validate_conn
    conn.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 352, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/lib/python3/dist-packages/urllib3/util/ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)
Eliah Kagan
  • 117,780
  • There is no way to safely upgrade 10.10 to 20.04. – Pilot6 Apr 27 '20 at 10:11
  • sorry, that is a typo, should be 19.10 to 20.04 corrected it, thank you – dazed-n-confused Apr 27 '20 at 10:45
  • This may not be relevant to you but I had a similar issue after upgrading to 20.04 and the fix was to go through and try upgrading the other packages in my requirements.txt file. It turns out some of them were quiet old and didn't work with the new OpenSSL on 20.04. – Dan Goldin Apr 28 '20 at 00:47
  • @Dan, That is a good idea, I checked and unfortunately, none of the many updates resolved the OpenSSL error message. Cheers. – dazed-n-confused Apr 28 '20 at 10:46
  • @dazed-n-confused - that's unfortunate. Good luck with the research and fix. – Dan Goldin Apr 30 '20 at 01:51
  • I have this same issue. I am able to run things fine on 2 separate Ubuntu 20.04 laptops if I use venv 3.8 but not my 20.04 or 18.04 rpi's. I've upgraded all pip packages and can even run this on a pi with raspbian stretch. The ubuntu pis get the same exact errors you are seeing.

    I've even downgraded certain python packages without success. The raspbian pi even has earlier versions of everything even python itself. Tried the /etc/ssl/openssl.cnf file edits but no dice.

    I'm really stumped. Pretty certain it's an openssl issue along with the pi version of ubuntu but idk for sure.

    – RobHimself Jun 29 '20 at 18:39
  • 1
    After upgrading to Ubuntu 20.04.1 the code works, happy days! – dazed-n-confused Aug 13 '20 at 20:49

2 Answers2

1

I experienced this error after upgrading from 18.04 LTS to 20.04 LTS, whilst trying to connect to an Exchange server. The cause is because the default upstream Debian OpenSSL settings have become more secure. In OpenSSL, CipherString is now set to DEFAULT@SECLEVEL=2

The background/rationale for this change is detailed here: https://weakdh.org/

Ideally, the server's security should be improved rather than implementing this work-around on the client. However, in many cases, this will not be possible.

I was able to workaround it by adjusting the ciphers used for the connection by creating an SSLContext. Here is an example of the code (for SMTPS connection - sending an e-mail):

connection = smtplib.SMTP(
    config['Email']['host'] + ':' + config['Email']['port'])
context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# Either of the following context settings worked for me - choose one
# context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')
connection.starttls(context=context)
connection.login(config['Email']['user'], config['Email']['pw'])
connection.sendmail(config['Email']['sender'], recipients, msg.as_string())
connection.close()

The important lines are these - chose one of these CipherString adjustments:

context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')

BUT prefer a server fix, if at all possible!

To adapt the above for urllib3, see this answer:

How to select specific the cipher while sending request via python request module

moo
  • 878
1

I was able to get my project to work after I lowered the SSL security level as outlined in this post.

Ubuntu 20.04 - how to set lower SSL security level?