Search code examples
pythoncryptographyx509public-key

Verify Apple's signature


I'm trying to verify a signature according to the documentation. Here is an example:

# cryptography==37.0.4
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
import base64

data = b"demo data"
signature = b"demo signature"

public_key_base64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWdp8GPcGqmhgzEFj9Z2nSpQVddayaPe4FMzqM9wib1+aHaaIzoHoLN9zW4K8y4SPykE3YVK3sVqW6Af0lfx3gg=="
public_key_bytes = base64.b64decode(public_key_base64)
apple_public_key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), public_key_bytes)

apple_public_key.verify(
    signature,
    data,
    ec.ECDSA(hashes.SHA256())
)

from_encoded_point generates:

    raise ValueError("Unsupported elliptic curve point type")
ValueError: Unsupported elliptic curve point type

Also tried different approaches from chat GPT but none works. Could you provide a working example please?


Solution

  • The key appears to be a base64 encoded SubjectPublicKeyInfo formatted public key. The cryptography module provide a general method for decoding these for all the public key types it supports via the cryptography.hazmat.primitives.serialization module. Thus, the fix is simply to replace

    apple_public_key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), public_key_bytes)
    

    with the much simpler

    apple_public_key = serialization.load_der_public_key(public_key_bytes)
    

    and of course add serialization to the relevant import statement:

    from cryptography.hazmat.primitives import hashes, serialization