Skip to content

Commit be69c4e

Browse files
authored
Merge pull request #59 from wi6n3l/master
Added Independent RSA Script
2 parents 3a04ba9 + c720845 commit be69c4e

File tree

2 files changed

+160
-1
lines changed

2 files changed

+160
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ This is a collection of short Python scripts to solve and automate tasks and sim
5353
32 | [**JSON-YAML**](https://github.com/decipher07/Useful-Python-scripts-collection/blob/master/JSON-YAML) | A Python script which converts JSON To YAML and Vice-Versa | JSON, YAML |
5454
33 | [**CSV_to_JSON**](https://github.com/TechBoyy6/Python-scripts-collection/tree/master/CSV_to_JSON) | A script that converts the csv file into json file. | None |
5555
34 | [**SMS-SENDER**](https://github.com/CopyrightC/Python-scripts-collection/blob/master/SMS_SENDER/main.py) | A python script that uses Tkinter and Twilio to send SMS. | twilio|
56-
35 | [**Password Validator**](https://github.com/Mannuel25/Python-scripts-collection/tree/master/Password%20Validator) | A script validates passwords to match specific rules. A valid password is one that conforms to some specific rules. | None |
56+
35 | [**Password Validator**](https://github.com/Mannuel25/Python-scripts-collection/tree/master/Password%20Validator) | A script validates passwords to match specific rules. A valid password is one that conforms to some specific rules. | None |
57+
36 | [**RSA Communication**](https://github.com/fnplus/Python-scripts-collection/tree/master/RSA_Communication) | Independent Python script that allows RSA communication. | None |

RSA_Communication/RSA.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#Modulus (N) bit length, k.
2+
#OUTPUT: An RSA key pair ((N,e),d) where N is the modulus, the product of two primes (N=pq) not exceeding k bits in length;
3+
# e is the public exponent, a number less than and coprime to (p−1)(q−1);
4+
# and d is the private exponent such that e*d ≡ 1 mod (p−1)*(q−1).
5+
##############################################################
6+
#Select a value of e from 3,5,17,257,65537 (easy operations)
7+
# while p mod e = 1
8+
# p = genprime(k/2)
9+
#
10+
# while q mode e = 1:
11+
# q = genprime(k - k/2)
12+
#
13+
#N = p*q
14+
#L = (p-1)(q-1)
15+
#d = modinv(e, L)
16+
#return (N,e,d)
17+
18+
from random import randrange, getrandbits
19+
import base64
20+
21+
class rsa():
22+
23+
def __init__(self, e=4, k=5):
24+
self.e = [3, 5, 17, 257, 65537][e]
25+
self.k = [128, 256, 1024, 2048, 3072, 4096][k]
26+
27+
def is_prime(self, n, tests=128):
28+
if n == 2 or n == 3:
29+
return True
30+
if n <= 1 or n % 2 == 0:
31+
return False
32+
s = 0
33+
r = n - 1
34+
while r & 1 == 0:
35+
s += 1
36+
r //= 2
37+
for _ in range(tests):
38+
a = randrange(2, n - 1)
39+
x = pow(a, r, n)
40+
if x != 1 and x != n - 1:
41+
j = 1
42+
while j < s and x != n - 1:
43+
x = pow(x, 2, n)
44+
if x == 1:
45+
return False
46+
j += 1
47+
if x != n - 1:
48+
return False
49+
return True
50+
51+
def genprime(self, length=1024):
52+
p = 1
53+
while len(bin(p))-2 != length:
54+
p = list(bin(getrandbits(length)))
55+
p = int(''.join(p[0:2] + ['1', '1'] + p[4:]), 2)
56+
p += 1 if p % 2 == 0 else 0
57+
58+
ip = self.is_prime(p)
59+
while not ip:
60+
p += 2
61+
ip = self.is_prime(p)
62+
63+
return p
64+
65+
def egcd(self, a, b):
66+
if a == 0:
67+
return (b, 0, 1)
68+
else:
69+
g, y, x = self.egcd(b % a, a)
70+
return (g, x - (b // a) * y, y)
71+
72+
def modinv(self, a, m):
73+
g, x, y = self.egcd(a, m)
74+
if g != 1:
75+
raise Exception('modular inverse does not exist')
76+
else:
77+
return x % m
78+
79+
def get_creds(self, e, k):
80+
N = 0
81+
while len(bin(int(N)))-2 != k:
82+
p = self.genprime(int(k/2))
83+
while pow(p, 1, e) == 1:
84+
p = self.genprime(int(k/2))
85+
q = self.genprime(k - int(k/2))
86+
while pow(q, 1, e) == 1 and q == p:
87+
q = self.genprime(k - int(k/2))
88+
N = p*q
89+
L = (p-1)*(q-1)
90+
d = self.modinv(e, L)
91+
return p, q, (d, e, N)
92+
93+
def get_keys(self):
94+
p, q, creds = self.get_creds(self.e, self.k)
95+
return creds
96+
97+
def save_keys(self, filename="keys.k"):
98+
keys = self.get_keys()
99+
with open(filename, "w", encoding="utf-8") as file:
100+
file.write(str(keys[0]) + "\n" + str(keys[1]) + "\n" + str(keys[2]))
101+
102+
def load_keys(self, filename="keys.k"):
103+
with open(filename, "r", encoding="utf-8") as file:
104+
f = file.read().split("\n")
105+
d = int(f[0])
106+
e = int(f[1])
107+
n = int(f[2])
108+
return (d, e, n)
109+
110+
def encrypt(self, ke, plaintext):
111+
key, n = ke
112+
b64_string = base64.b64encode(plaintext.encode("utf-8")).decode("utf-8")
113+
ready_code = []
114+
for char in list(b64_string):
115+
ready_code.append('0' * (3 - len(str(ord(char)))) + str(ord(char)))
116+
ready_code = int("1" + "".join(ready_code))
117+
cipher = pow(ready_code, key, n)
118+
return cipher
119+
120+
def decrypt(self, kd, ciphertext):
121+
key, n = kd
122+
plain_list = list(str(pow(ciphertext, key, n)))[1:]
123+
plain = []
124+
count = 1
125+
temp = ""
126+
for i in plain_list:
127+
if count != 4:
128+
temp += i
129+
count += 1
130+
else:
131+
plain.append(temp)
132+
temp = i
133+
count = 2
134+
plain.append(temp)
135+
plain_list = plain
136+
plain = base64.b64decode(''.join([chr(int(char)) for char in plain_list])).decode("utf-8")
137+
return plain
138+
139+
encryption = rsa()
140+
keys = encryption.get_keys()
141+
142+
d = keys[0]
143+
e = keys[1]
144+
n = keys[2]
145+
146+
print("key: \n" + str(e) + "/" + str(n))
147+
148+
while True:
149+
choose = input("Encrypt (e)/ Decrypt (d) > ")
150+
if choose == "e":
151+
e, n = input("insert key > ").split("/")
152+
to_encrypt = input("message to encrypt > ")
153+
a = encryption.encrypt((int(e), int(n)), to_encrypt)
154+
print(a)
155+
elif choose == "d":
156+
to_decrypt = input("message to decrypt > ")
157+
a = encryption.decrypt((d, n), to_decrypt)
158+
print(a)

0 commit comments

Comments
 (0)