forked from jpf/okta-jwks-to-pem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pem_to_jwks.py
executable file
·77 lines (58 loc) · 1.72 KB
/
pem_to_jwks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#! /usr/bin/env nix-shell
#! nix-shell -i python -p python27Packages.cryptography
# This is, essentially, the reverse of "jwks_to_pem.py".
# Given a PEM encoded public key, it will extract the modulus and exponent
# from the key and return JWKS formatted JSON
input_key = ""
import struct
import base64
import argparse
import fileinput
import sys
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
parser = argparse.ArgumentParser()
parser.add_argument('--kid',
default="example",
help='JWK Key ID to include in output.')
parser.add_argument('key',
metavar='FILE',
nargs='?',
help='PEM encoded public key. Use "-" for STDIN.')
args = parser.parse_args()
input_file = args.key
if input_file is None:
parser.print_help()
sys.exit(1)
for line in fileinput.input(files=input_file):
input_key += line
def long2intarr(long_int):
_bytes = []
while long_int:
long_int, r = divmod(long_int, 256)
_bytes.insert(0, r)
return _bytes
def long_to_base64(n):
bys = long2intarr(n)
data = struct.pack('%sB' % len(bys), *bys)
if not len(data):
data = '\x00'
s = base64.urlsafe_b64encode(data).rstrip(b'=')
return s.decode("ascii")
pem_data = input_key
public_key = serialization.load_pem_public_key(
input_key,
backend=default_backend())
public_numbers = public_key.public_numbers()
jwk = {
"alg": "RS256",
"e": None,
"n": None,
"kid": args.kid,
"kty": "RSA",
"use": "sig"
}
jwk['n'] = long_to_base64(public_numbers.n)
jwk['e'] = long_to_base64(public_numbers.e)
import json
print json.dumps(jwk)