Mensaje de error
cryptography.exceptions.InvalidSignature
La excepción se lanza sin texto de mensaje: el traceback termina con el nombre de la clase, sin más (reproducido con cryptography 50.0).
Python cryptography — raised by verify()
Qué significa
public_key.verify(signature, data, ...) determinó que la firma no se verifica para estos datos con esta clave. Todo se analizó correctamente; simplemente, la comprobación falló. Como la excepción no lleva detalles por diseño, el diagnóstico consiste en probar cada entrada por separado: la clave, los bytes de los datos, la codificación de la firma y el hash.
Por qué ocurre
Firma r‖s en formato raw donde se espera DER
frecuenteEl verify() de ECDSA en cryptography recibe DER ASN.1. Una firma raw de 64 bytes procedente de WebCrypto, de JWS o del modo «raw» de otra biblioteca no se notifica como mal formada: verify() lanza el mismo InvalidSignature sin detalles que lanzaría una falsificación, y por eso esta confusión pasa desapercibida con tanta facilidad.
Los bytes de los datos son distintos
frecuenteDiferencias de codificación entre str y bytes, un salto de línea final, una reserialización JSON con otro orden de claves u otros espacios en blanco: verify() firma/verifica bytes exactos, y «semánticamente idéntico» no es idéntico.
Doble hash por un mal uso de Prehashed
frecuenteverify(sig, data, ec.ECDSA(hashes.SHA256())) calcula por sí mismo el hash de data. Pasar un resumen ya calculado sin utils.Prehashed vuelve a calcular el hash del resumen: una de las 3 causas más frecuentes de fallos de verificación misteriosos.
Clave o hash incorrectos
ocasionalUna clave pública rotada o que no corresponde, o verificar con SHA-256 lo que se firmó con SHA-384. El hash forma parte del esquema de firma, no es un parámetro libre.
Cómo solucionarlo
- 1.
Convertir las firmas raw a DER
Si la firma tiene 64 bytes (P-256), divídela en r y s y vuelve a codificarla como DER antes de verificarla.
python from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature r = int.from_bytes(raw_sig[:32], "big") s = int.from_bytes(raw_sig[32:], "big") der_sig = encode_dss_signature(r, s) public_key.verify(der_sig, message, ec.ECDSA(hashes.SHA256())) - 2.
Usar Prehashed para resúmenes precalculados
Si tienes el resumen en lugar del mensaje, indícalo explícitamente; si no, la biblioteca calcula el hash de tu hash.
python from cryptography.hazmat.primitives.asymmetric import utils public_key.verify( der_sig, digest_bytes, # already SHA-256(message) ec.ECDSA(utils.Prehashed(hashes.SHA256())), ) - 3.
Averiguar qué entrada es incorrecta
Pega la clave, el mensaje y la firma en la herramienta de diagnóstico de errores de abajo: prueba las hipótesis de discrepancia habituales —hash incorrecto, raw frente a DER, doble hash, normalización high-S, curva incorrecta— e indica cuál hace que tu firma se verifique.