Skip to content

Instantly share code, notes, and snippets.

@jonlundy
Last active February 15, 2024 00:12
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jonlundy/f25c99ee0770e19dc595 to your computer and use it in GitHub Desktop.
Save jonlundy/f25c99ee0770e19dc595 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# SPDX-License-Identifier: MIT
import sys,json,base64,binascii
with open(sys.argv[1]) as fp:
pkey=json.load(fp)
def enc(data):
missing_padding = 4 - len(data) % 4
if missing_padding:
data += b'='* missing_padding
return '0x'+binascii.hexlify(base64.b64decode(data,b'-_')).upper()
for k,v in pkey.items():
if k == 'kty': continue
pkey[k] = enc(v.encode())
print "asn1=SEQUENCE:private_key\n[private_key]\nversion=INTEGER:0"
print "n=INTEGER:{}".format(pkey[u'n'])
print "e=INTEGER:{}".format(pkey[u'e'])
print "d=INTEGER:{}".format(pkey[u'd'])
print "p=INTEGER:{}".format(pkey[u'p'])
print "q=INTEGER:{}".format(pkey[u'q'])
print "dp=INTEGER:{}".format(pkey[u'dp'])
print "dq=INTEGER:{}".format(pkey[u'dq'])
print "qi=INTEGER:{}".format(pkey[u'qi'])
# Create a DER encoded private key
openssl asn1parse -noout -out private_key.der -genconf <(python conv.py private_key.json)
# Convert to PEM
openssl rsa -in private_key.der -inform der
@jvanasco
Copy link

would you mind if i include some of this in a MIT licensed project (with credit)?

@szepeviktor
Copy link

@jsabater
Copy link

Hi, Jon!

Just tried to use your tool to convert a private_key.json from the latest version of Certbot to PEM format using Python 3.9 under Debian 11 Bullseye and found this error:

Traceback (most recent call last):
  File "/home/ansible/bin/jwk_convert.py", line 31, in <module>
    PKEY[k] = enc(v.encode())
  File "/home/ansible/bin/jwk_convert.py", line 26, in enc
    return '0x'+binascii.hexlify(base64.b64decode(data, b'-_')).upper()
TypeError: can only concatenate str (not "bytes") to str

I had converted the script to Python 3 using 2to3 but handling strings of bytes seems to need specific knowledge, which I don't have. I think the problem is here:

data += b'=' * missing_padding

I've tried to research this topic without success. Would you feel like upgrading the script to Python 3? I think that the need to convert JWK to PEM is going to be there for a while for all us Ansible users.

Incidentally, I'd love to create an Ansible Playbook to do the whole process, maybe through a module.

Thanks in advance and happy new year.

@ivanov17
Copy link

Hi, @jsabater!

You can try my fork of this script. I updated it for python3.6 a few years ago and it works fine for me.

@jonlundy, can you provide a free license for your script? Would you be so kind as to add a comment with a SPDX-License-Identifier to the header?

@jonlundy
Copy link
Author

hey. @jvanasco @szepeviktor @jsabater @ivanov17

I am so sorry that I did not see any of your comments till now. I have added a license header. Feel free to use this or @ivanov17 's version as its a great update to the code.

Thanks!

@jvanasco
Copy link

Thanks! I already used a variation of this within a larger function, but did credit it to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment