I want to convert a certificate to the jwks simulating jwks endpoint. I don't know how to efficiently extract kty, alg, kid, use fields from certificate object.
import base64
import json
import jwt
import requests
import hashlib
from cryptography import x509
from cryptography.hazmat.primitives._serialization import Encoding
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
def int_to_bytes(n):
n_bytes = n.to_bytes((n.bit_length() + 7) // 8, 'big')
# Step 2: Encode the bytes in base64url format
n_b64url = base64.urlsafe_b64encode(n_bytes).rstrip(b'=').decode()
return n_b64url
cert_str = """-----BEGIN CERTIFICATE-----
MIIHWDCCBkCgAwIBAgITfgACgcRnkOPT4howKgABAAKBxDANBgkqhkiG9w0BAQsF ....O7
-----END CERTIFICATE-----"""
cert_obj = load_pem_x509_certificate(cert_str.encode(), default_backend())
public_key = cert_obj.public_key()
public_numbers = public_key.public_numbers()
# Get the DER-encoded version of the certificate
cert_der = cert_obj.public_bytes(encoding=Encoding.DER)
# Compute the SHA-1 hash of the DER-encoded certificate
hash_sha1 = hashlib.sha1(cert_der).digest()
# Base64Url encode the hash
x5t = base64.urlsafe_b64encode(hash_sha1).rstrip(b'=').decode()
print(f"The x5t of the certificate is: {x5t}")
jwks = {
"keys": [
{
"kty": "RSA", # <- How to extract from certificate
"e": int_to_bytes(public_numbers.e),
"use": "sig", # <- How to extract from certificate
"kid": "ZTdjMg_RS256", # <- How to extract from certificate
"x5t": x5t,
"alg": "RS256", # <- How to extract from certificate
"n": int_to_bytes(public_numbers.n)
}
]
}
So how to extract kty, alg, kid, use?
I have not generalizable silly method:
from cryptography.hazmat.primitives.asymmetric import rsa, ec, dsa
# Assuming `public_key` is your public key object
if isinstance(public_key, rsa.RSAPublicKey):
print("The key uses the RSA algorithm family.")
elif isinstance(public_key, ec.EllipticCurvePublicKey):
print("The key uses the Elliptic Curve algorithm family.")
elif isinstance(public_key, dsa.DSAPublicKey):
print("The key uses the DSA algorithm family.")
else:
print("Unknown algorithm family.")
but how to set up those fields from certificate?