本文へスキップ
ecdsa.com
OpenSSL (server side: nginx, Apache, Postfix, openssl s_server)OpenSSL CLI

エラーメッセージ

SSL routines:tls_post_process_client_hello:no shared cipher

別の表記

  • SSL_do_handshake() failed (SSL: error:0A0000C1:SSL routines::no shared cipher)
  • error:0A0000C1:SSL routines::no shared cipher

openssl s_server(OpenSSL 3.x)は「error:0A0000C1:SSL routines:tls_post_process_client_hello:no shared cipher:<source>」と記録します。nginx は「SSL_do_handshake() failed (SSL: error:0A0000C1:SSL routines::no shared cipher) while SSL handshaking」を info レベルで記録するため、error_log のデフォルトのレベルでは表示されません。OpenSSL 1.1.1 ではコード 1417A0C1 でした。

OpenSSL (server side: nginx, Apache, Postfix, openssl s_server) — SSL_R_NO_SHARED_CIPHER

このエラーの意味

これは、失敗したハンドシェイクをサーバー側から見たエラーです。クライアントの ClientHello に含まれる暗号スイートの中に、サーバーで有効になっていて、かつサーバー証明書の鍵で使用できるものがありませんでした。サーバーはその後、クライアントに handshake_failure(アラート 40)を送信します。このエラーはサーバーのログに表示され、クライアントの出力には表示されません。

発生する理由

修正方法

  1. 1.

    証明書の鍵と暗号スイートが合っているか確認する

    ECDHE-ECDSA-* の暗号スイートには ECDSA 証明書が、ECDHE-RSA-* には RSA 証明書が必要です。両方の証明書を持つサーバーは、両方の系統を列挙できます。

    bash
    # ECDSA key + only ECDHE-RSA suites (or the reverse) leaves nothing usable
    openssl x509 -in server.pem -noout -text | grep 'Public Key Algorithm'
    openssl ciphers -v 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256'
  2. 2.

    サーバーが実際に受け入れる暗号スイートを一覧にする

    外部から暗号スイートを列挙し、サポートが必要なクライアントと比較してください。

    bash
    # Which TLS 1.2 suites does the server accept? (nmap needed)
    nmap --script ssl-enum-ciphers -p 443 api.example.com
  3. 3.

    十分にテストされた暗号スイートのリストを使う

    リストを手作業で削るのではなく、生成した最新(Modern)または中間(Intermediate)プロファイルの設定から始めてください。

    text
    # nginx: suites for both RSA and ECDSA certificates, TLS 1.3 enabled
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;

関連するエラー

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