Certificate Decoder · Security
Certificate Decoder & Chain Checker: Decodifique cada campo X.509 e verifique cada assinatura da cadeia.
Cole um certificado, um fullchain.pem ou a saída completa do openssl s_client -showcerts. Cada campo X.509 é decodificado, a ordem da cadeia é conferida e corrigida com o motivo do erro, e cada elo recebe um veredito real de assinatura — verificada, falhou, ou não verificada com o algoritmo nomeado. Uma chave privada na colagem é pulada, nunca interpretada e nunca enviada a lugar algum: não existe aqui servidor para onde enviá-la.
Roda no seu navegador — nada do que você cola sai desta página. Como comprovamos isso
Playground do decodificador de certificado e verificador de cadeia
Paste a certificate, a fullchain.pem, or the whole output of openssl s_client -showcerts — everything outside the BEGIN/END markers is ignored. A private key is recognised and skipped, never parsed: there is no server here to send it to.
Results update as you type — press Enter to run now.
RFC 6125: a wildcard covers exactly one leftmost label, and an IP address must appear as an IP SAN. commonName is only consulted when the certificate has no SAN at all.
No share links on this tool — inputs may be secrets.
Paste a certificate or a whole chain to see every field decoded, the chain order checked, and each signature verified — all inside this tab.
A lacuna
No seu navegador funciona. Isso não é prova.
Um navegador conserta para você uma cadeia de certificados quebrada. Se falta um intermediário, Chrome e Safari podem baixá-lo pela URL authorityInfoAccess do próprio certificado, ou reaproveitar um que ficou em cache num site sem relação: o cadeado aparece e a falha continua invisível. curl, Go, Python e qualquer runner de CI não fazem nada disso. Usam exatamente os certificados enviados e falham com unable to get local issuer certificate. Essa assimetria é a forma mais comum de um deploy de certificado passar na conferência manual e quebrar um webhook às duas da manhã.
A outra metade do problema é que a saída de um certificado é ilegível de propósito. openssl x509 -text são 60 linhas de hexadecimal por certificado, cadeias não têm ordem visível, e a pergunta que você realmente tem — falta algo, algo expirou, isso cobre o meu nome de host — não está em lugar nenhum daquele despejo. Esta página responde a essas três perguntas primeiro e mantém a lista completa de campos abaixo.
É também a pergunta errada para fazer a um chatbot. Um modelo de linguagem que lê um despejo de certificado está casando padrões de texto: lê notAfter do certificado errado, erra a aritmética de datas nos dois sentidos, afirma tranquilamente que um curinga cobre dois rótulos e não consegue verificar assinatura nenhuma, porque verificar uma exige realmente fazer a conta. Esta página interpreta o DER byte a byte e passa a assinatura pelo Web Crypto — assim você confere a resposta que recebeu contra um resultado que consegue reproduzir com openssl na sua própria máquina.
Está lidando com um token em vez de um certificado? O JWT Decoder lê e verifica um JWS, e o gerador de hash calcula o mesmo SHA-256 com que você compararia uma impressão digital.
O pipeline
Como funciona.
Cinco passos determinísticos, todos dentro da aba do seu navegador — um leitor DER escrito à mão que devolve null em vez de lançar exceção, e Web Crypto para a única parte que é criptografia de verdade.
-
Achar os blocos e ignorar todo o resto.
Só o texto entre os marcadores BEGIN e END é lido, então uma transcrição do openssl s_client pode ser colada como está. Um bloco PRIVATE KEY é reconhecido pelo rótulo e pulado sem ser interpretado; a um CSR ou a um pacote PKCS#7 se diz o que ele é e qual comando o converte.
-
De base64 para DER, de DER para estrutura.
Um leitor escrito à mão percorre o DER — nenhuma biblioteca de parsing, portanto nada lança exceção diante de uma colagem estragada. DER é uma codificação canônica, e é isso que permite a um leitor mínimo ser exato em vez de apenas tolerante: construções que só existem em BER, como comprimentos indefinidos, são recusadas em vez de adivinhadas.
-
Ler X.509 do jeito que a RFC 5280 define.
Número de série como decimal exato em BigInt, um RDN multivalorado unido em vez de achatado, o pivô de UTCTime em 2049 respeitado e SANs IPv4 e IPv6 formatados corretamente. Os valores aparecem literalmente: um decodificador que “limpasse” o que está no certificado estaria escondendo exatamente o que você veio ver.
-
Ligar a cadeia por identificador de chave, não por nome.
O authorityKeyIdentifier de cada certificado é comparado ao subjectKeyIdentifier do emissor, de modo que uma AC renovada com o mesmo nome da anterior se resolve corretamente e um par com assinatura cruzada é relatado como par com assinatura cruzada, não como duplicata.
-
Verificar cada assinatura com Web Crypto.
Os bytes assinados são a fatia tbsCertificate, conferida contra a chave pública do emissor: RSA PKCS#1 v1.5 com SHA-1/256/384/512, ECDSA em P-256/384/521 e Ed25519 onde o navegador tiver. Cada elo é verificado, falhou ou não verificado com o algoritmo nomeado — nunca um booleano cru.
Referência
O erro que você recebeu e o que ele quer dizer.
Nove mensagens cobrem quase toda falha de certificado em produção. A maioria delas é a mesma dupla de causas — um intermediário ausente, ou um nome que não está na lista de SAN — vestida com as palavras de fornecedores diferentes.
| Mensagem | O que significa de fato |
|---|---|
| unable to get local issuer certificate curl, openssl, Python, Node | A cadeia termina abaixo de uma raiz em que o cliente confia: falta um intermediário. Anexe-o ao arquivo que o servidor envia. |
| x509: certificate signed by unknown authority Go | A mesma falha nas palavras do Go: ou um intermediário ausente, ou uma raiz de AC privada em que esta máquina não confia. |
| self-signed certificate in certificate chain curl, openssl | A cadeia inclui um certificado autoassinado em que o cliente não confia. Em geral uma raiz de AC privada; às vezes uma raiz enviada sem necessidade. |
| self-signed certificate curl, openssl | A folha emitiu a si mesma. Nada externo garante o nome: aceitável numa máquina de teste, nunca num endpoint público. |
| NET::ERR_CERT_AUTHORITY_INVALID Chrome, Edge | O navegador não conseguiu montar um caminho até uma raiz confiável: um intermediário ausente que ele não pôde baixar, ou uma AC não confiável. |
| NET::ERR_CERT_COMMON_NAME_INVALID Chrome, Edge | Nenhum subjectAltName casa com o nome de host. Um commonName correto não ajuda — os navegadores pararam de lê-lo em 2017. |
| NET::ERR_CERT_DATE_INVALID · certificate has expired em todo lugar | notAfter está no passado, ou notBefore no futuro, ou o relógio da máquina que reclama está errado. |
| certificate is not yet valid curl, openssl, Java | notBefore ainda não chegou. Ou o certificado foi emitido antes de uma rotação, ou há desvio de relógio: confira as duas pontas. |
| unsupported certificate purpose openssl verify | O extendedKeyUsage não inclui serverAuth, então o certificado não serve para autenticação de servidor TLS. |
Como é a ordem correta da cadeia
A folha primeiro, depois cada intermediário. A raiz é opcional — e, quando está presente, são apenas bytes, porque a confiança vem do repositório do próprio cliente.
fullchain.pem — leaf first, root optional and last
1 CN = shop.example.com ← leaf (CA:FALSE, carries the SANs)
2 CN = Example Labs Intermediate R3 ← signs the leaf (CA:TRUE, pathlen:0)
3 CN = Example Labs Root X1 ← self-signed; the client already has it
each certificate's authorityKeyIdentifier
points at the subjectKeyIdentifier of the one below it Pegue a cadeia e depois confira a afirmação
Uma ferramenta de verdade de referência deveria ser conferível contra outra coisa. Cada impressão digital desta página é o SHA-256 do DER completo — os mesmos bytes que o openssl x509 -fingerprint resume.
# The chain your server actually sends, ready to paste above
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# The claim this page makes is checkable against openssl on your own machine
openssl x509 -in isrgrootx1.pem -noout -fingerprint -sha256
SHA256 Fingerprint=96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:
CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6
# ...and against the value ISRG publishes for Root X1. Three sources, one answer. Próximo passo
A cadeia está certa. Agora confira o que ela protege.
Um certificado é um elo numa cadeia de coisas que precisam concordar: o JWT Decoder lê e verifica os tokens que o endpoint distribui, o gerador de hash calcula o resumo com que você compara uma impressão digital, e o Reverse DNS / PTR Helper confere se o nome do certificado é o nome que resolve. Todos, como esta página, rodam inteiramente no seu navegador.
3 certificates — chain order OK
leaf shop.example.com notAfter 2031-06-01
intermediate Example Labs Intermediate R3
root Example Labs Root X1 self-signed
signature verified leaf ← intermediate RSA PKCS#1 v1.5 with SHA-256
signature verified int ← root RSA PKCS#1 v1.5 with SHA-256
hostname www.shop.example.com covered by *.shop.example.com FAQ
Suas perguntas, respondidas.
Toque em uma pergunta para expandir a resposta.
O que significa “unable to get local issuer certificate”?
Significa que a cadeia enviada pelo seu servidor termina antes de chegar a algo em que o cliente confia — quase sempre porque falta um certificado intermediário. O cliente sobe a partir da folha: folha → intermediário → raiz. No repositório dele só existem raízes, então, se o intermediário que liga as duas pontas está ausente, o caminho morre ali e o OpenSSL devolve o erro 20 com exatamente essa mensagem. Cole sua cadeia aqui e o intermediário ausente aparece nomeado pelo distinguished name completo, que é justamente o texto de que você precisa para achar o arquivo certo e anexá-lo.
Por que meu certificado funciona no navegador e falha no curl ou na CI?
Porque navegadores consertam cadeias incompletas e clientes de linha de comando não. Quando falta um intermediário, Chrome, Edge e Safari podem baixá-lo pela URL da extensão authorityInfoAccess do próprio certificado, ou reaproveitar um que ficou em cache em outro site: o cadeado aparece e o defeito permanece invisível. curl, openssl s_client, crypto/tls do Go, requests do Python e quase todos os runtimes não fazem nada disso: usam exatamente os certificados que você enviou e falham. Essa assimetria é a razão pela qual “no meu navegador funciona” não é prova, e é a causa mais comum de um deploy que passa na conferência manual e quebra um webhook.
O fullchain.pem deve incluir o certificado raiz?
Não — e também não faz mal. Um cliente confia numa raiz porque essa raiz já está no repositório dele; uma cópia enviada pela rede não prova nada, porque um atacante poderia enviar qualquer raiz. Portanto isso só acrescenta cerca de 1–2 KB a cada handshake. O que precisa estar lá é a folha primeiro e depois cada intermediário acima dela. Esta ferramenta rotula cada certificado com o seu papel e diz em qual das duas situações você está: uma raiz meramente redundante, ou um intermediário que de fato falta.
Qual é a diferença entre folha, intermediário e raiz?
A folha é o certificado do seu nome de host: carrega a lista subjectAltName, tem CA:FALSE nos basicConstraints e é o que o servidor apresenta. Um intermediário é um certificado de AC que assina folhas em nome de uma raiz; tem CA:TRUE, normalmente com pathlen:0 para não poder delegar mais adiante. Uma raiz é um certificado de AC que assinou a si mesmo — subject e issuer são idênticos — e só se confia nela porque ela vem embutida em sistemas operacionais e navegadores. As ACs mantêm raízes offline e assinam por meio de intermediários justamente para que uma chave de assinatura comprometida possa ser trocada sem reemitir a raiz.
Esta ferramenta diz se um certificado é confiável?
Deliberadamente não — e essa é a resposta honesta, não uma limitação a contornar. “Confiável” é propriedade do cliente, não do certificado: Chrome, Firefox, macOS, Windows e o seu runtime Java carregam listas de raízes diferentes, e raízes deixam de ser confiadas entre versões. Embutir uma cópia de um repositório de confiança nesta página permitiria imprimir um “confiável” categórico para uma raiz que o Chrome removeu no mês passado — exatamente a classe de resposta confiante e errada que esta ferramenta existe para pegar. O que ela faz, em vez disso, é aritmética verificável: a cadeia é coerente consigo mesma, cada assinatura foi verificada contra a chave de cima, e as impressões digitais estão ali para você comparar com o que a AC publica.
Como um certificado wildcard realmente casa com um nome de host?
Um curinga substitui exatamente um rótulo, e apenas o mais à esquerda (RFC 6125 §6.4.3). Assim, *.example.com casa com api.example.com e www.example.com; não casa com a.b.example.com, porque isso exigiria dois rótulos, e não casa com example.com puro, porque não há rótulo para substituir — por isso os certificados normalmente listam o apex como um segundo SAN. Um curinga também nunca é aceito nos dois rótulos de cima (*.com não significa nada) nem dentro de um rótulo (w*.example.com não é um padrão válido). O campo de nome de host desta página aplica cada uma dessas regras e diz qual delas decidiu o veredito.
É seguro colar aqui um certificado — ou uma chave privada?
Um certificado é público por definição: é enviado em texto claro no início de todo handshake TLS e, para qualquer certificado publicamente confiável, já está publicado em logs de Certificate Transparency. Não há o que proteger. Uma chave privada é o oposto, e esta página ainda assim a trata com segurança: a ferramenta inteira é uma página estática sem servidor por trás, então, se você colar um bloco PRIVATE KEY, ele é reconhecido pelo rótulo, nunca é interpretado e nunca é enviado a lugar algum — a página diz isso explicitamente. A maioria dos decodificadores de certificado não pode afirmar o mesmo, porque envia sua entrada para um backend. Se você colou uma chave em um deles, faça a rotação.
Por que uma assinatura às vezes aparece como “não verificada” em vez de “falhou”?
Porque são duas respostas completamente diferentes, e misturá-las seria mentira. “Falhou” significa que a chave pública do emissor foi aplicada à assinatura e não bateu: o certificado foi alterado, ou aquele não é o emissor. “Não verificada” significa que a checagem não pôde ser feita, e o motivo é sempre nomeado: RSASSA-PSS carrega hash, tamanho de sal e função de máscara dentro dos seus parâmetros e esta ferramenta se recusa a adivinhá-los; SHA-224, MD5 e DSA não são implementados pelo Web Crypto; Ed25519 exige Chrome 137 ou Safari 17. Um booleano imprimiria “não verificada” para tudo isso e deixaria você ler como “falsificada”. Cada elo da cadeia aqui tem três estados, nunca dois.
Meu certificado tem o commonName certo. Por que os navegadores ainda o recusam?
Porque os navegadores pararam de ler o commonName em 2017. Chrome 58 e Firefox 48 removeram esse recurso de reserva, e todo cliente atual exige que o nome de host apareça na extensão subjectAltName: um certificado com um CN perfeito e sem SAN não casa com nada e produz NET::ERR_CERT_COMMON_NAME_INVALID. Continua válido colocar o nome também no CN, e a maioria das ACs faz isso, mas é decoração. Esta ferramenta mostra a lista de SAN separada do subject exatamente por esse motivo, e avisa quando um certificado não tem SAN nenhum.
More free, private DevOps tools.
O Certificate Decoder é uma das ferramentas do OpsCanopy — uma copa crescente de validadores, conversores e testadores que rodam no navegador e nunca tocam um servidor.
Mais em Segurança
39 ferramentas gratuitas, todas capazes de funcionar offline — o opscanopy.com não exige cadastro e não envia nada.
Ferramentas de segurança relacionadas: o JWT Decoder, o gerador de hash para os resumos por trás de uma impressão digital e o Reverse DNS / PTR Helper para conferir se o nome do certificado é o nome que resolve — ou navegue pelo diretório completo de ferramentas.
Fornecido como está, para sua conveniência. Esta página relata o que há dentro de um certificado e se cada assinatura fecha; ela não afirma — e nunca vai afirmar — que um certificado é confiável: confiança mora no repositório de raízes do cliente, e aqui também não há checagem de revogação nem de Certificate Transparency (ambas precisam de rede). OpsCanopy é grátis e aberto.