Mensagem de erro
Invalid EC key. Point is not on the curve specified.
Reproduzido no cryptography 50.0. EllipticCurvePublicKey.from_encoded_point() relata a mesma falha de forma mais concisa, como “Invalid EC key.”. Outras implementações formulam de outro jeito — a pilha de erros do OpenSSL 1.1 diz “point is not on curve”, e o Node rejeita a JWK com “Invalid JWK EC key” —, mas a matemática por trás de todas é idêntica.
Python cryptography — ValueError from EllipticCurvePublicNumbers.public_key()
O que significa
O par (x, y) que você forneceu não satisfaz a equação y² = x³ + ax + b (mod p) da curva que você indicou. As bibliotecas validam isso na importação porque aceitar pontos fora da curva possibilita ataques de curva inválida, que podem vazar chaves privadas — então a rejeição é uma verificação de segurança, não um preciosismo. A verificação é uma única avaliação barata da equação da curva, e toda biblioteca séria a faz: um ponto fora da curva vai ser rejeitado em algum lugar, e é melhor que isso aconteça aqui, de forma explícita, do que mais adiante.
Por que acontece
Coordenadas associadas à curva errada
comumUm ponto secp256k1 (Bitcoin/Ethereum) declarado como SECP256R1/P-256 — ou vice-versa. As duas curvas usam coordenadas de 32 bytes, então nada mais detecta a troca; a equação da curva detecta.
Bytes de coordenada corrompidos ou truncados
comumUm zero à esquerda removido (coordenada de 31 bytes), hex decodificado com um erro de off-by-one, confusão entre base64 e base64url ou um único bit invertido — qualquer alteração em x ou y quase certamente tira o ponto da curva.
Ordem de bytes errada
ocasionalAs coordenadas são big-endian em todas as codificações padrão. Bytes invertidos para little-endian (algo comum na integração com hardware ou com código feito à mão) descrevem um ponto completamente diferente — e fora da curva.
Como corrigir
- 1.
Construir a chave a partir do ponto codificado, com a curva certa
from_encoded_point valida o tamanho e a estrutura em um só passo; tente a outra curva candidata se a origem dos dados for ambígua.
python from cryptography.hazmat.primitives.asymmetric import ec point = b"\x04" + x_bytes + y_bytes # uncompressed, 65 bytes for P-256 key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), point) # if that raises, test: ec.SECP256K1() — the other 256-bit suspect - 2.
Conferir os dados brutos
Confirme os tamanhos de 32 bytes e se os valores são plausíveis antes de construir a chave; restaure os zeros removidos com padding à esquerda.
python print(len(x_bytes), len(y_bytes)) # must be 32, 32 for P-256 x_bytes = x_bytes.rjust(32, b"\x00") # repair stripped leading zeros y_bytes = y_bytes.rjust(32, b"\x00")