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

エラーメッセージ

x509: certificate specifies an incompatible key usage

別の表記

  • tls: failed to verify certificate: x509: certificate specifies an incompatible key usage

TLS クライアントでは、先頭に「tls: failed to verify certificate:」が付きます。クライアント証明書を検証する Go のサーバーは、「http: TLS handshake error from <addr>: tls: failed to verify certificate: x509: certificate specifies an incompatible key usage」とログに記録します。

Go crypto/x509 — CertificateInvalidError (IncompatibleUsage): extendedKeyUsage does not allow this role

このエラーの意味

チェーンは信頼されていますが、証明書の extendedKeyUsage(または中間証明書のもの。Go はこれもチェックします)が、証明書が使われている役割を許可していません。serverAuth のないサーバー証明書や、相互 TLS で clientAuth のないクライアント証明書がこれに当たります。Go は EKU を厳格に適用します。ほかの TLS スタックの中にはより寛容なものもあるため、同じ証明書がほかの環境では動作することがあります。

発生する理由

修正方法

  1. 1.

    各証明書の extendedKeyUsage を確認する

    リーフ証明書とすべての中間証明書を確認してください。必要な用途が、パス全体で許可されていなければなりません。

    bash
    # Leaf and intermediates: which purposes do they allow?
    openssl x509 -in server.pem -noout -ext extendedKeyUsage,keyUsage
    #   TLS Web Server Authentication = serverAuth, TLS Web Client Authentication = clientAuth
  2. 2.

    正しい EKU で再発行する

    サーバー証明書には serverAuth を、クライアント証明書には clientAuth を設定してください(同じ証明書でどうしても両方の役割を担う必要がある場合は両方を設定します)。

    bash
    # Server certificates need serverAuth; for mutual TLS client certificates need clientAuth
    openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \
      -addext "subjectAltName=DNS:api.example.com" -addext "extendedKeyUsage=serverAuth"
  3. 3.

    相互 TLS:clientAuth を含むクライアント証明書を発行する

    RequireAndVerifyClientCert を設定した Go のサーバーは、クライアント証明書の EKU に clientAuth が含まれているかをチェックします。

    go
    // Go server verifying client certificates: they need clientAuth (or no EKU at all)
    cfg := &tls.Config{
    	ClientAuth: tls.RequireAndVerifyClientCert,
    	ClientCAs:  clientCAPool,
    }

関連するエラー

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