Pular para o conteúdo
ecdsa.com
OpenSSLCLI do OpenSSL

Mensagem de erro

SSL routines:ssl3_read_bytes:ssl/tls alert bad certificate

Também aparece como

  • SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
  • error:0A000412:SSL routines::ssl/tls alert bad certificate

O OpenSSL 3.3 e posteriores imprimem “ssl/tls alert bad certificate”; as versões anteriores, “sslv3 alert bad certificate” (código 0A000412; o 1.1.1 usava 14094412), seguido de “SSL alert number 42”. Os próprios clientes OpenSSL enviam unknown_ca (48) ou certificate_expired (45) nas mesmas rejeições.

OpenSSL — TLS alert 42 (bad_certificate) received from the peer

O que significa

O peer enviou o alerta TLS 42 (bad_certificate): ele rejeitou o certificado que este lado apresentou. O crypto/tls do Go envia esse alerta para qualquer certificado de servidor que não consegue verificar (autoridade desconhecida, expirado, nome errado), por isso servidores baseados em OpenSSL (nginx, HAProxy, Postfix, s_server) o registram sempre que um cliente Go rejeita o certificado deles. No TLS mútuo, um servidor o envia quando rejeita o certificado do cliente.

Por que acontece

Como corrigir

  1. 1.

    Descobrir qual cliente rejeitou o certificado e por quê

    A linha do log traz o endereço do cliente; nesse cliente, a mensagem de erro informa a causa real. Verificar a cadeia de fora muitas vezes já mostra a causa diretamente.

    bash
    # Server log: which client rejected the certificate, and does the chain verify from outside?
    openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null \
      | grep -E 'Verify return code'
  2. 2.

    Clientes Go: confiar na CA ou corrigir a cadeia

    Sirva uma cadeia completa de uma CA confiável ou adicione a CA privada ao RootCAs do cliente Go; nunca use InsecureSkipVerify como solução.

    go
    // Go clients: trust the server's CA explicitly (keeps verification on)
    pool, _ := x509.SystemCertPool()
    caPEM, _ := os.ReadFile("internal-ca.pem")
    pool.AppendCertsFromPEM(caPEM)
    client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: pool}}}
  3. 3.

    TLS mútuo: verificar o certificado de cliente

    As datas de validade, o emissor e o uso da chave do certificado de cliente precisam corresponder ao que o servidor espera.

    bash
    # Mutual TLS: check the client certificate the server rejected
    openssl x509 -in client.pem -noout -issuer -dates -ext extendedKeyUsage,keyUsage

Erros relacionados

Ver toda a base de erros de assinatura