Перейти к содержимому
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 или клиентский сертификат без clientAuth при взаимной TLS-аутентификации. 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

    Серверы на Go с RequireAndVerifyClientCert проверяют, есть ли clientAuth в EKU клиентского сертификата.

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

Связанные ошибки

Открыть всю базу ошибок подписей