Skip to content

EC to_jwk #466

@dimaqq

Description

@dimaqq

I've notices that RSA keys have a to_jwk() function in pyjwt, but EC keys do not.

I've cobbled together a dirty conversion routine:
(shared under MIT license)

import sys
import json
from base64 import urlsafe_b64encode
import cryptography.hazmat.backends.openssl.backend
import cryptography.hazmat.primitives.serialization


def toBase64url(v: int):
    return (
        urlsafe_b64encode(v.to_bytes(100, "big").lstrip(b"\0"))
        .decode("ascii")
        .rstrip("=")
    )


def jwk_format(public_key: str, key_id: str = 1) -> dict:
    """JSON Web Key format for a public key."""
    key = cryptography.hazmat.primitives.serialization.load_pem_public_key(
        public_key.encode("ascii"), cryptography.hazmat.backends.openssl.backend
    )

    JWK_CURVE_NAMES = {"secp256r1": "P-256"}

    return {
        "epk": {
            "kty": "EC",
            "crv": JWK_CURVE_NAMES[key.public_numbers().curve.name],
            "x": toBase64url(key.public_numbers().x),
            "y": toBase64url(key.public_numbers().y),
            "kid": key_id,
        }
    }

if __name__ == "__main__":
    json.dump(jwk_format(open(sys.argv[1]).read()), sys.stdout, indent=2)

Given this input:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0vYjQm7oEHaJTjZ9Hh35aTd20h/U
wiz3RbYsoaGGjXGXu/d+9k7HdfsD4RjpjZFIOdurtnY0JBZkSrhZCipyaw==
-----END PUBLIC KEY-----

It produces the output:

{
  "epk": {
    "kty": "EC",
    "crv": "P-256",
    "x": "0vYjQm7oEHaJTjZ9Hh35aTd20h_Uwiz3RbYsoaGGjXE",
    "y": "l7v3fvZOx3X7A-EY6Y2RSDnbq7Z2NCQWZEq4WQoqcms",
    "kid": 1
  }
}

If someone wants to drop this into the codebase, that would be great!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions