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

Solution 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

Solution 2:

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?