Skip to content

Instantly share code, notes, and snippets.

@kezzyhko
Last active September 27, 2020 18:56
Show Gist options
  • Save kezzyhko/49418184f7665be445d1f45bf1af910f to your computer and use it in GitHub Desktop.
Save kezzyhko/49418184f7665be445d1f45bf1af910f to your computer and use it in GitHub Desktop.
Prints .pem private RSA key given p, q and e
# This code is compilation of
# 1) code from
# https://0day.work/how-i-recovered-your-private-key-or-why-small-keys-are-bad/
# 2) modified version of code snippet from crypto stackexchange
# https://crypto.stackexchange.com/a/25499
# This code does not perform any checks on p, q and e and can give wrong result
# or throw not informative exception if p, q and/or e are not valid.
import pyasn1.codec.der.encoder
import pyasn1.type.univ
import base64
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
gcd, x, y = egcd(a, m)
if gcd != 1:
return None # modular inverse does not exist
else:
return x % m
def pempriv(p, q, e):
d = modinv(e,(p-1)*(q-1))
n = p*q
dP = d % p
dQ = d % q
qInv = pow(q, p - 2, p)
template = '-----BEGIN RSA PRIVATE KEY-----\n{}-----END RSA PRIVATE KEY-----'
seq = pyasn1.type.univ.Sequence()
for i,x in enumerate((0, n, e, d, p, q, dP, dQ, qInv)):
seq.setComponentByPosition(i, pyasn1.type.univ.Integer(x))
der = pyasn1.codec.der.encoder.encode(seq)
return template.format(base64.encodebytes(der).decode('ascii'))
if __name__ == "__main__":
if (len(sys.argv) != 4):
print("Wrong number of arguments.")
print("Usage: \"{}\" prime_p prime_q exponent".format(sys.argv[0]))
else:
print(pempriv(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3])), end = '')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment