Mensagem de erro
[SSL: DH_KEY_TOO_SMALL] dh key too small
Seguido de uma localização no código-fonte, como “(_ssl.c:1082)”. O curl e outros clientes baseados no OpenSSL imprimem o mesmo motivo como “dh key too small”.
Python ssl module (OpenSSL, security level 2) — ssl.SSLError, SSL_R_DH_KEY_TOO_SMALL
O que significa
O servidor escolheu uma troca de chaves Diffie-Hellman de corpo finito (DHE) com um grupo menor do que o cliente aceita, normalmente de 1024 bits. O Python 3.10 e posteriores usam o nível de segurança 2 do OpenSSL, que exige DH de pelo menos 2048 bits, então o cliente aborta o handshake. O certificado do servidor não é o problema.
Por que acontece
O servidor usa um grupo DH de 1024 bits
comumVersões antigas do Apache httpd (antes da 2.4.7, usavam parâmetros fixos de 1024 bits), servidores mais antigos baseados em Java e configurações que ainda carregam um arquivo dhparam gerado anos atrás. A pesquisa Logjam (2015) mostrou que DH de 1024 bits está ao alcance de atacantes com muitos recursos.
O nível de segurança padrão mais rigoroso do Python
comumO Python 3.10 elevou o padrão para o nível de segurança 2 do OpenSSL. Um código que se conectava sem problemas no Python 3.9 pode falhar depois de uma atualização, embora o servidor não tenha mudado.
Dispositivos embarcados e equipamentos dedicados
ocasionalInterfaces de gerenciamento de impressoras, centrais telefônicas (PBX) e equipamentos industriais muitas vezes só oferecem DHE com grupos pequenos.
Como corrigir
- 1.
Confirmar o tamanho da troca de chaves
Conecte uma vez no nível de segurança 1 com openssl s_client e leia “Server Temp Key”.
bash # "Server Temp Key: DH, 1024 bits" confirms the weak group openssl s_client -connect legacy.example.com:443 -servername legacy.example.com \ -cipher 'DEFAULT:@SECLEVEL=1' </dev/null 2>/dev/null | grep 'Server Temp Key' - 2.
Donos do servidor: usar ECDHE ou um grupo de 2048 bits
Prefira cipher suites ECDHE (e o TLS 1.3); se o DHE for obrigatório, configure um grupo da RFC 7919 de pelo menos 2048 bits.
text # nginx: prefer ECDHE; if DHE must stay, use a 2048-bit (or larger) group ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_dhparam /etc/nginx/ffdhe2048.pem; # RFC 7919 group - 3.
Solução temporária: reduzir o nível de segurança para um único host
“DEFAULT:@SECLEVEL=1” em um contexto dedicado aceita DH de 1024 bits só para esse host. Não use essa string em contextos compartilhados ou padrão: ela também aceita outros parâmetros fracos.
python # Temporary workaround for one legacy host: security level 1 accepts 1024-bit DH import ssl, urllib.request ctx = ssl.create_default_context() ctx.set_ciphers("DEFAULT:@SECLEVEL=1") urllib.request.urlopen("https://legacy.example.com/", context=ctx)
Erros relacionados
[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] ssl/tls alert handshake failurePython ssl module (OpenSSL)[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabledPython ssl module (OpenSSL 3)curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handsh…curl (OpenSSL backend)