O cryptography é o que a maior parte do código Python — PyJWT, Authlib, paramiko, certbot, os SDKs da AWS e do Google — usa para a criptografia de verdade. Sua camada hazmat expõe chaves e assinaturas diretamente; os wheels trazem o próprio OpenSSL, então o comportamento segue a versão do pacote, e não o sistema operacional (a 50.0.2 vem com o OpenSSL 4.0.3).
As assinaturas ECDSA saem em ASN.1 DER, e verify() espera DER. O WebCrypto, o JWS e a maioria dos tokens de hardware usam a forma r‖s bruta de 64 bytes, que verify() rejeita com o mesmo InvalidSignature de uma assinatura forjada. decode_dss_signature e encode_dss_signature convertem entre DER e o par de inteiros; o padding de largura fixa fica por sua conta, exatamente como mostra o exemplo, ou use o conversor DER ⇄ bruto para conferir manualmente.
O nonce é aleatório, a menos que você peça a RFC 6979: ec.ECDSA(hashes.SHA256(), deterministic_signing=True) reproduziu exatamente o vetor de teste P-256 da RFC — inclusive o s high-S do vetor, porque nada no pacote normaliza o s, e a verificação aceita as duas metades. Assinaturas destinadas a um verificador low-S, como a libsecp256k1 ou a @noble/curves, precisam antes ter o s substituído por n − s. sign() e verify() calculam o hash dos dados por conta própria; passe Prehashed(hashes.SHA256()) quando já tiver um digest, senão o hash será calculado duas vezes.
A cobertura de curvas é ampla — da P-224 à P-521, a secp256k1 e as curvas Brainpool r1 —, além de Ed25519, Ed448, ML-KEM-768/1024 e ML-DSA-44/65/87 na 50.0.2. As chaves são carregadas de PEM e DER (SPKI, PKCS#8, PKCS#8 criptografado, SEC1), OpenSSH e pontos SEC1 isolados; não há leitor de JWK, então JWKs passam pelo PyJWT, pelo Authlib ou pelo jwcrypto, ou pelo conversor de JWK.
A maioria dos erros que as pessoas pesquisam vem do carregamento de chaves, e não da assinatura: uma chave pública passada a load_pem_private_key, uma chave criptografada sem senha ou um ponto que não está na curva indicada. O verificador de assinaturas e a matriz de interoperabilidade de bibliotecas ajudam quando uma assinatura vinda de outra stack não passa na verificação.