Pular para o conteúdo
ecdsa.com
Python cryptographyPython (cryptography)

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

Como corrigir

  1. 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. 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")

Erros relacionados

Ver toda a base de erros de assinatura