-
Notifications
You must be signed in to change notification settings - Fork 0
/
rsatool3.py
85 lines (75 loc) · 3.11 KB
/
rsatool3.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
78
79
80
81
82
83
84
85
#!/usr/bin/python3
from Crypto.PublicKey.RSA import construct
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import optparse
import gmpy
DEFAULT_EXP = 65537
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):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-p', dest='p', help='prime', type='int')
parser.add_option('-q', dest='q', help='prime', type='int')
parser.add_option('-n', dest='n', help='modulus', type='int')
parser.add_option('-d', dest='d', help='private exponent', type='int')
parser.add_option('-e', dest='e', help='public exponent (default: %d)' % DEFAULT_EXP, type='int', default=DEFAULT_EXP)
parser.add_option('-o', dest='filename', help='output filename')
parser.add_option('-f', dest='format', help='output format (DER, PEM) (default: PEM)', type='choice', choices=['DER', 'PEM'], default='PEM')
try:
(options, args) = parser.parse_args()
privkey=None
if options.p and options.q:
if not gmpy.is_prime(options.p) or not gmpy.is_prime(options.q):
raise ValueError("Supplied p and or supplied q is not a prime number!")
print('Using (p, q) to initialise RSA instance\n')
n = options.p * options.q
if options.p != options.q:
phi = (options.p - 1) * (options.q - 1)
else:
phi = (options.p ** 2) - options.p
d = modinv(options.e, phi)
privkey = construct((n, options.e, d))
elif options.n and options.d:
print('Using (n, d) to initialise RSA instance\n')
privkey = construct((options.n, options.e, options.d))
else:
parser.print_help()
parser.error('Either (p, q) or (n, d) needs to be specified')
if privkey:
print(f"n = {privkey.n}")
print(f"e = {privkey.e}")
print(f"d = {privkey.d}")
print(f"p = {privkey.p}")
print(f"q = {privkey.q}")
keystring = privkey.exportKey()
if options.format == 'DER':
pemkey = serialization.load_pem_private_key(
keystring,
None,
default_backend()
)
derkey = pemkey.private_bytes(
serialization.Encoding.DER,
serialization.PrivateFormat.TraditionalOpenSSL,
serialization.NoEncryption()
)
keystring = derkey
if options.filename:
print(f"Saving key in {options.format} format to file {options.filename}.")
tf = open(options.filename, 'wb')
tf.write(keystring)
tf.close()
except optparse.OptionValueError as e:
parser.print_help()
parser.error(e.msg)