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
Coordenadas emparejadas con la curva equivocada
frecuenteUn punto secp256k1 (Bitcoin/Ethereum) declarado como SECP256R1/P-256, o al revés. Ambas curvas usan coordenadas de 32 bytes, así que nada más detecta el cambio; la ecuación de la curva, sí.
Bytes de coordenadas dañados o truncados
frecuenteUn cero inicial eliminado (coordenada de 31 bytes), un hex decodificado con un error off-by-one, la confusión entre base64 y base64url o un solo bit invertido: cualquier cambio en x o en y casi con total seguridad saca el punto de la curva.
Orden de bytes incorrecto
ocasionalLas coordenadas son big-endian en todas las codificaciones estándar. Los bytes invertidos a little-endian (algo habitual al interactuar con hardware o con código hecho a mano) describen un punto completamente distinto y fuera de la curva.
Cómo solucionarlo
- 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.
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")