Signing jwt with coincurve (python)

#1

I try to implement something like DID auth for OI Chat. On the server with python I use coincurve to verify the jwt signature:

    pwd = password.encode("utf-8")
    try:
        signing_input, crypto_segment = pwd.rsplit(b".", 1)
        header_segment, payload_segment = signing_input.split(b".", 1)
    except ValueError:
        raise DecodeError("Not enough segments")
    payload = self.base64url_decode(payload_segment)
    payload = json.loads(payload.decode("utf-8"))
    publicKey = payload["public_keys"][0]
    pubKey = bytes.fromhex(publicKey)
    sig = bytes.fromhex(crypto_segment.hex())
    coincurve.verify_signature(sig, payload_segment,  pubKey)

This fails with The DER-encoded signature could not be parsed.
Am I using the method incorrectly?

The full code can be found here:

In particular in feature branch jwt-auth:

To run a test just call python3 matrix_blockstack_password_provider/test.py

Any help to make the test past would be appreciated.
There is a question on bitcoin stackoverflow, however, I am not sure how to apply the answer to my code. Is the public key in DER format? https://bitcoin.stackexchange.com/questions/86043/question-about-python-library-coincurve-libsecp256k

Is there a (better) package to verify ES256k signatures?

#2

I can’t speak to coincurve (never used it). I know that our JWT format isn’t standardized by the W3C (because ES256k1 isn’t standard). Can you sign something with coincurve and verify it with jsontokens-js at least? Is it possible to sign the same JSON object with coincurve and jsontokens-js and compare the resulting JWTs?

#3

I tried to sign the same token as in https://github.com/blockstack/jsontokens-js/blob/master/src/test/mainTests.ts

But the results are not the same. Do I have to use a different encoding?

    privateKey = coincurve.PrivateKey.from_hex("278a5de700e29faae8e40e366ec5012b5ec63d36ec77e8a2417154cc1d25383f")
    jwt = privateKey.sign("{\"issuedAt\":\"1440713414.85\",\"challenge\":\"7cd9ed5e-bb0e-49ea-a323-f28bde3a0549\",\"issuer\":{\"publicKey\":\"03fdd57adec3d438ea237fe46b33ee1e016eda6b585c3e27ea66686c2ea5358479\",\"chainPath\":\"bd62885ec3f0e3838043115f4ce25eedd22cc86711803fb0c19601eeef185e39\",\"publicKeychain\":\"xpub661MyMwAqRbcFQVrQr4Q4kPjaP4JjWaf39fBVKjPdK6oGBayE46GAmKzo5UDPQdLSM9DufZiP8eauy56XNuHicBySvZp7J5wsyQVpi2axzZ\",\"blockchainid\":\"ryan\"}}".encode("utf-8"))
    logger.info(base64.urlsafe_b64encode(jwt))

The result is

b'MEQCIFpiUT5BsuGQnGYXWHeNDXZWrAt6Nf0SVHoEIjsH3VtTAiAnjxf-6NWmuQtLD6_nm7PcGxSV9Y2le0xpDByaNCqz0A=='

With jsontoken.js the result is
signature:

'oO7ROPKq3T3X0azAXzHsf6ub6CYy5nUUFDoy8MS22B3TlYisqsBrRtzWIQcSYiFXLytrXwAdt6vjehj3OFioDQ'

or

 'DUf6Rnw6FBKv4Q3y95RX7rR6HG_L1Va96ThcIYTycOf1j_bf9WleLsOyiZ-35Qfw7FgDnW7Utvz4sNjdWOSnhQ'

Do you have any ideas what is wrong? Is there an alternative to coincurve in python?