Created
August 19, 2025 11:24
-
-
Save akrabat/b69c23ab935caa5cd27f257aa0d775f5 to your computer and use it in GitHub Desktop.
Revisions
-
akrabat created this gist
Aug 19, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,91 @@ #!/usr/bin/env -S uv run --script --quiet # /// script # dependencies = [ # "cryptography", # ] # /// """Convert JWK keys to PEM format. This script reads .well-known/jwks.json and outputs PEM encoded versions of the public keys in that file. This file should be set as executable (chmod +x jwk-to-pem.py). Usage: curl -s https://example.com/.well-known/jwks.json | jwk-to-pem.py uv run jwk-to-pem.py jwks.json uv run jwk-to-pem.py < jwks.json Requirements: - uv (https://github.com/astral-sh/uv) - cryptography library Author: Rob Allen <[email protected]> Copyright 2025 License: MIT License - https://opensource.org/licenses/MIT """ import json import base64 import sys from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa def base64url_decode(data): """Decode base64url to bytes""" # Add padding if needed padding = 4 - len(data) % 4 if padding != 4: data += '=' * padding # Replace URL-safe chars data = data.replace('-', '+').replace('_', '/') # Decode return base64.b64decode(data) def jwk_to_pem(jwk_key): """Convert JWK to PEM format""" if jwk_key['kty'] != 'RSA': raise ValueError("Only RSA keys are supported") # Decode the modulus (n) and exponent (e) to int n = int.from_bytes(base64url_decode(jwk_key['n']), 'big') e = int.from_bytes(base64url_decode(jwk_key['e']), 'big') # Create RSA public key public_key = rsa.RSAPublicNumbers(e, n).public_key() # Serialize to PEM pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) return pem.decode() def main(): if len(sys.argv) > 2: print("Usage: jwk_to_pem.py [jwks.json]") print("If no file is provided, reads from stdin") sys.exit(1) if len(sys.argv) == 2 and sys.argv[1] != '-': # Read from file with open(sys.argv[1], 'r') as f: jwks = json.load(f) else: # Read from stdin jwks = json.load(sys.stdin) # Convert each key for i, key in enumerate(jwks['keys']): kid = key.get('kid', f'key-{i}') print(f"# Key {i} (kid: {kid})") print(jwk_to_pem(key)) if __name__ == "__main__": main()