本文へスキップ
ecdsa.com
Go crypto/tls clientGo

エラーメッセージ

remote error: tls: handshake failure

HTTP クライアントでは、「Get \"https://…\": remote error: tls: handshake failure」という行になります。クライアントがアラートを送信した場合、Go はサーバー側でも同じ「remote error: tls: <alert>」の形式を使い、「http: TLS handshake error from …」というログ行に出力します。

Go crypto/tls client — the server sent TLS alert 40 (handshake_failure)

このエラーの意味

「remote error」は、相手側が TLS アラートを送信したことを意味します。この場合は、サーバーが Go クライアントにアラート 40(handshake_failure)を送信しています。サーバーが Go の提示したパラメーター(暗号スイート、グループ、署名アルゴリズム)を拒否したか、Go が送信しなかったクライアント証明書を要求したかのどちらかです。どちらなのかは Go 側では判断できませんが、サーバーのログでわかります。

発生する理由

修正方法

  1. 1.

    暗号スイートを比較する

    tls.CipherSuites() は、Go が安全とみなして提示する暗号スイートを列挙します。これをサーバーの設定と比較してください。

    go
    // What does this Go client offer by default?
    for _, s := range tls.CipherSuites() {
    	fmt.Println(s.Name)
    }
  2. 2.

    相互 TLS のクライアント証明書を送信する

    tls.LoadX509KeyPair で証明書と鍵を読み込み、tls.Config.Certificates に設定してください。

    go
    // Mutual TLS: present a client certificate
    cert, err := tls.LoadX509KeyPair("client.pem", "client.key")
    if err != nil {
    	log.Fatal(err)
    }
    client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{
    	Certificates: []tls.Certificate{cert},
    }}}
  3. 3.

    サーバー管理者:暗号スイートを最新のものにする

    TLS 1.3 の暗号スイートと、ECDHE ベースの TLS 1.2 の暗号スイートは、現行のすべての Go リリースで動作します。

    text
    Server side: enable TLS 1.3 and TLS 1.2 ECDHE suites with AES-GCM or ChaCha20-Poly1305.

関連するエラー

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