跳到主要内容
ecdsa.com
Python cryptographyPython cryptography 库

错误信息

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

在 cryptography 50.0 上复现。EllipticCurvePublicKey.from_encoded_point() 对同样的失败给出更简短的报告:“Invalid EC key.”。其他技术栈的措辞各不相同——OpenSSL 1.1 的错误栈写的是“point is not on curve”,Node 则以“Invalid JWK EC key”拒绝该 JWK——但它们背后的数学原理完全相同。

Python cryptography — ValueError from EllipticCurvePublicNumbers.public_key()

含义

你提供的 (x, y) 坐标对不满足你所指定曲线的方程 y² = x³ + ax + b (mod p)。各个库在导入时都会校验这一点,因为接受不在曲线上的点会让无效曲线攻击成为可能,进而泄露私钥——所以这种拒绝是一项安全检查,而不是吹毛求疵。这项检查只需代入曲线方程计算一次,开销很小,所有成熟的库都会执行:不在曲线上的点总会在某处被拒绝,与其在下游出问题,不如在这里明确地报错。

原因

修复方法

  1. 1.

    用正确的曲线,从编码后的点构建密钥

    from_encoded_point 一步完成长度和结构的校验;如果数据来源不明确,就换另一条候选曲线试试。

    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.

    检查原始数据

    构建之前,确认长度为 32 字节且数值合理;在左侧用零填充,恢复被去掉的前导零。

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

相关错误

浏览完整的签名错误库