Mensagem de erro
Verification failure
Este é o texto do OpenSSL 3.x. O OpenSSL 1.1.x escreve com iniciais maiúsculas: “Verification Failure”. O openssl pkeyutl -verify imprime a variante “Signature Verification Failure”. No OpenSSL 3.x, as duas vêm acompanhadas de uma linha da pilha de erros, como “error:030000EA:digital envelope routines:EVP_DigestVerifyFinal:provider signature failure” (reproduzido no 3.6). Uma assinatura que nem sequer está em DER nunca chega até aqui: ela falha com “Error verifying data”.
O que significa
O openssl dgst -verify calculou o digest dos seus dados, verificou a assinatura com a chave pública, e a matemática disse não. Chave, dados e assinatura estavam todos legíveis — um dos três não corresponde aos outros dois. Para comparação, a saída em caso de sucesso é “Verified OK”.
Por que acontece
Os dados diferem do que foi assinado
comumUma quebra de linha no final adicionada por um editor, a conversão entre CRLF e LF feita pelo git ou o cálculo de um novo hash sobre algo que já é um digest (o dgst calcula o hash da entrada — se você passar a ele um digest SHA-256, o que se assina é o hash do hash).
Digest divergente
comumAssinado com -sha256, mas verificado com -sha384 (ou a biblioteca do signatário usou outro hash por padrão). O digest faz parte do que é assinado; os dois lados precisam usar o mesmo.
Chave pública errada
ocasionalUma chave rotacionada, a chave de outro serviço ou uma chave pública derivada de uma chave privada diferente da que assinou.
Como corrigir
- 1.
Descartar primeiro a codificação da assinatura
O dgst -verify só lê assinaturas ECDSA em ASN.1 DER. Uma assinatura raw r‖s do WebCrypto, de JWS ou de uma API Go/Python em modo raw — exatamente 64 bytes para P-256, 96 para P-384 — falha antes, com “Error verifying data”. Se a sua está em DER e ainda assim falha aqui, os dados, o digest ou a chave estão errados. A ferramenta DER ⇄ raw abaixo converte entre as duas formas e sinaliza valores high-S não canônicos, que verificadores rigorosos rejeitam.
- 2.
Verificar um digest pré-calculado com o pkeyutl
Quando você tem o digest, e não a mensagem, o dgst é a ferramenta errada (ele calcularia o hash de novo). O pkeyutl verifica a assinatura com o digest bruto.
bash openssl dgst -sha256 -binary message.bin > msg.hash openssl pkeyutl -verify -pubin -inkey pub.pem \ -sigfile sig.der -in msg.hash -pkeyopt digest:sha256 - 3.
Eliminar divergências nos dados
Compare os digests dos bytes exatos nos dois lados; qualquer diferença significa que quem mudou foi a mensagem, e não a criptografia.
bash openssl dgst -sha256 message.bin # run on signer and verifier sides xxd message.bin | tail -2 # check for a sneaky trailing 0a