本文へスキップ
ecdsa.com
Python ssl module (OpenSSL, security level 2)Python の cryptography

エラーメッセージ

[SSL: DH_KEY_TOO_SMALL] dh key too small

その後に「(_ssl.c:1082)」のようなソースの位置が続きます。curl などの OpenSSL クライアントは、同じ理由を「dh key too small」と出力します。

Python ssl module (OpenSSL, security level 2) — ssl.SSLError, SSL_R_DH_KEY_TOO_SMALL

このエラーの意味

サーバーが、クライアントが受け入れるより小さいグループ(通常は 1024 ビット)で有限体 Diffie-Hellman(DHE)鍵交換を選択しました。Python 3.10 以降は OpenSSL のセキュリティレベル 2 を使い、2048 ビット以上の DH を必須とするため、クライアントがハンドシェイクを中止します。サーバーの証明書には問題はありません。

発生する理由

修正方法

  1. 1.

    鍵交換のサイズを確認する

    openssl s_client を使ってセキュリティレベル 1 で一度接続し、「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. 2.

    サーバー管理者:ECDHE または 2048 ビットのグループを使う

    ECDHE の暗号スイート(と TLS 1.3)を優先してください。DHE が必要な場合は、2048 ビット以上の RFC 7919 のグループを設定してください。

    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. 3.

    一時的な回避策:1 つのホストに限ってセキュリティレベルを下げる

    専用のコンテキストで「DEFAULT:@SECLEVEL=1」を指定すると、そのホストに限って 1024 ビットの DH を受け入れます。ほかの弱いパラメーターも受け入れてしまうため、共有のコンテキストやデフォルトのコンテキストには設定しないでください。

    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)

関連するエラー

署名エラーデータベースをすべて見る