Saltar al contenido
ecdsa.com
Python cryptographycryptography de Python

Mensaje de error

Invalid EC key. Point is not on the curve specified.

Reproducido en cryptography 50.0. EllipticCurvePublicKey.from_encoded_point() informa del mismo fallo de forma más escueta, como «Invalid EC key.». Otros entornos lo formulan de otra manera —la pila de errores de OpenSSL 1.1 dice «point is not on curve», Node rechaza la JWK con «Invalid JWK EC key»—, pero la matemática que hay detrás de todos ellos es idéntica.

Python cryptography — ValueError from EllipticCurvePublicNumbers.public_key()

Qué significa

El par (x, y) que proporcionas no satisface la ecuación de la curva y² = x³ + ax + b (mod p) para la curva que indicas. Las bibliotecas lo validan al importar porque aceptar puntos fuera de la curva permite ataques de curva no válida que pueden filtrar claves privadas; por eso el rechazo es una comprobación de seguridad, no pedantería. La comprobación es una única evaluación barata de la ecuación de la curva, y toda biblioteca seria la hace: un punto fuera de la curva se rechazará en algún sitio, y mejor aquí, con un error explícito, que más adelante en el proceso.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Construir la clave a partir del punto codificado, con la curva correcta

    from_encoded_point valida la longitud y la estructura en un solo paso; si el origen es ambiguo, prueba con la otra curva candidata.

    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.

    Comprobar los datos en bruto

    Confirma longitudes de 32 bytes y valores plausibles antes de construir la clave; restaura los ceros eliminados rellenando por la izquierda.

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

Errores relacionados

Explorar toda la base de datos de errores de firma