makeprime.py
import random
from random import randint
def proBin(w): # w表示希望产生位数,生成目标位数的伪素数
list = []
list.append('1') # 最高位定为1
for _ in range(w - 2):
c = random.choice(['0', '1'])
list.append(c)
list.append('1') # 最低位定为1
res = int(''.join(list), 2)
return res
# 幂模运算
def X_n_mod_P(base, exponent, n):
bin_array = bin(exponent)[2:][::-1]
r = len(bin_array)
base_array = []
pre_base = base
base_array.append(pre_base)
for _ in range(r - 1):
next_base = (pre_base * pre_base) % n
base_array.append(next_base)
pre_base = next_base
a_w_b = __multi(base_array, bin_array, n)
return a_w_b % n
def __multi(array, bin_array, n):
result = 1
for index in range(len(array)):
a = array[index]
if not int(bin_array[index]):
continue
result *= a
result = result % n # 加快连乘的速度
return result
def MillerRabin(a, p): # 素性测试
if X_n_mod_P(a, p - 1, p) == 1:
u = (p-1) >> 1
while (u & 1) == 0:
t = X_n_mod_P(a, u, p)
if t == 1:
u = u >> 1
else:
if t == p - 1:
return True
else:
return False
else:
t = X_n_mod_P(a, u, p)
if t == 1 or t == p - 1:
return True
else:
return False
else:
return False
def testMillerRabin(p, k): # k为测试次数,p为待测奇数
while k > 0:
a = randint(2, p - 1)
if not MillerRabin(a, p):
return False
k = k - 1
return True
def makeprime(w): # 产生w位素数
while 1:
d = proBin(w)
for i in range(50): # 伪素数附近50个奇数都没有真素数的话,重新再产生一个伪素数
u = testMillerRabin(d+2*(i), 5)
if u:
b = d + 2*(i)
break
else:
continue
if u:
return b
else:
continue
if __name__ == "__main__": # 测试
print(makeprime(67))
RSA+模幂运算.py
import numpy as np
import tkinter
from makeprime import makeprime
# 字符与数字之间的映射转换
dict = {'a': '31', 'b': '32', 'c': '33', 'd': '34', 'e': '35', 'f': '36', 'g': '37',
'h': '38', 'i': '39', 'j': '10', 'k': '11', 'l': '12', 'm': '13', 'n': '14',
'o': '15', 'p': '16', 'q': '17', 'r': '18', 's': '19', 't': '20', 'u': '21',
'v': '22', 'w': '23', 'x': '24', 'y': '25', 'z': '26', '1': '41', '2': '42',
'3': '43', '4': '44', '5': '45', '6': '46', '7': '47', '8': '48', '9': '49',
'0': '40', ' ': '50', '\n': '51'}
# RSA参数初始化
p, q = 0, 0
n = 0
l = 0
e = 0
d = 0
'''
扩展欧几里的算法
计算 ax + by = 1中的x与y的整数解(a与b互质)
'''
def ext_gcd(a, b):
if b == 0:
x1 = 1
y1 = 0
x = x1
y = y1
r = a
return r, x, y
else:
r, x1, y1 = ext_gcd(b, a % b)
x = y1
y = x1 - a // b * y1
return r, x, y
'''
超大整数超大次幂然后对超大的整数取模
(base ^ exponent) mod n
'''
def exp_mode(base, exponent, n):
bin_array = bin(exponent)[2:][::-1]
r = len(bin_array)
base_array = []
pre_base = base
base_array.append(pre_base)
for _ in range(r - 1):
next_base = (pre_base * pre_base) % n
base_array.append(next_base)
pre_base = next_base
a_w_b = __multi(base_array, bin_array, n)
return a_w_b % n
def __multi(array, bin_array, n):
result = 1
for index in range(len(array)):
a = array[index]
if not int(bin_array[index]):
continue
result *= a
result = result % n # 加快连乘的速度
return result
def transferToNum(str):
m = ""
for d in str:
m += dict[d]
return m
def transferTostr(num):
n = ""
for i in range(0, len(num), 2):
n += {value: key for key, value in dict.items()}[num[i]+num[i+1]]
return n
def euler(p, q) -> int:
return (p-1)*(q-1)
def gcd(a, b):
if a < b:
return gcd(b, a)
while a % b != 0:
temp = b
b = a % b
a = temp
return b
def part1():
print("part1")
text_p1_N.delete("1.0", tkinter.END)
text_p1_L.delete("1.0", tkinter.END)
text_p1_E.delete("1.0", tkinter.END)
text_p1_D.delete("1.0", tkinter.END)
p = makeprime(int(entry_p1_p.get()))
q = makeprime(int(entry_p1_q.get()))
######### N ##############
n = p*q
text_p1_N.insert("insert", f"{n}={p}*{q}")
######### L ##############
l = (p-1)*(q-1)
text_p1_L.insert("insert", f"{l}=({p}-1)*({q}-1)")
######### E ##############
e = 65537 # 选取e 65537
text_p1_E.insert("insert", f"e选定为{e}")
######### D ##############
a = e
b = l
x = ext_gcd(a, b)[1]
if x < 0:
d = x + l
else:
d = x
text_p1_D.insert("insert", f"{d}")
entry_p1_public_key_E.insert("insert", f"{e}")
entry_p1_public_key_N.insert("insert", f"{n}")
entry_p1_private_key_D.insert("insert", f"{d}")
entry_p1_private_key_N.insert("insert", f"{n}")
def part2():
print("part2")
text_p2_plain_byte.delete("1.0", tkinter.END)
text_p2_cipher_text.delete("1.0", tkinter.END)
e = int(entry_p2_public_key_E.get())
n = int(entry_p2_public_key_N.get())
mingwen_text = text_p2_plain_text.get('1.0', tkinter.END)
plain_text = int(transferToNum(mingwen_text))
text_p2_plain_byte.insert("insert", f"plain_text={plain_text}")
cipher_text = exp_mode(plain_text, e, n)
text_p2_cipher_text.insert(
"insert", f"{cipher_text}={plain_text}^{e} % {n}")
def part3():
print("part3")
text_p3_plain_text.delete("1.0", tkinter.END)
text_p3_mingwen_text.delete("1.0", tkinter.END)
d = int(entry_p3_private_key_D.get())
n = int(entry_p3_private_key_N.get())
cipher_text = int(text_p3_cipher_text.get('1.0', tkinter.END))
plain_text = exp_mode(cipher_text, d, n)
text_p3_plain_text.insert(
"insert", f"{plain_text}={cipher_text}^{d} % {n}")
mignwen_text = transferTostr(str(plain_text))
text_p3_mingwen_text.insert(
"insert", f"mignwen_text={mignwen_text}")
# # 生成窗口之基本信息
root = tkinter.Tk()
root.geometry('1200x430') # 窗口的宽度x高度
root.resizable(False, False) # 窗口可以改变大小
root.title('RSA非对称密钥') # 设置窗口标题
root.config(bg='#ffffff') # 窗口背景颜色
###################################################
lable_part1 = tkinter.Label(root, text="Part①-RSA密钥生成", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p1_p = tkinter.Label(root, text="请输入质数p位数:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p1_p = tkinter.Entry(root, bd=5)
lable_p1_q = tkinter.Label(root, text="请输入质数q位数:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p1_q = tkinter.Entry(root, bd=5)
lable_p1_EDN = tkinter.Label(root, text="E、D、N的生成:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p1_N = tkinter.Label(root, text="1. N = p × q", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p1_N = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_L = tkinter.Label(root, text="2. L = (p-1) × (q-1)", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p1_L = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_E = tkinter.Label(root, text="3. E: gcd(E,L) = 1", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p1_E = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_D = tkinter.Label(root, text="4. D: E × D mod L = 1", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p1_D = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_public_key = tkinter.Label(root, text="公钥{E,N} = ", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p1_public_key_E = tkinter.Entry(root, bd=5)
entry_p1_public_key_N = tkinter.Entry(root, bd=5)
lable_p1_private_key = tkinter.Label(root, text="私钥{D,N} = ", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p1_private_key_D = tkinter.Entry(root, bd=5)
entry_p1_private_key_N = tkinter.Entry(root, bd=5)
button_p1 = tkinter.Button(
root, text="RSA密钥生成", font=("黑体", 13), command=part1)
###################################
lable_part2 = tkinter.Label(root, text="Part②-RSA加密过程", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p2_private_key = tkinter.Label(root, text="请输入公钥{E,N}:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p2_public_key_E = tkinter.Entry(root, bd=5)
entry_p2_public_key_N = tkinter.Entry(root, bd=5)
lable_p2_plain_text = tkinter.Label(root, text="请输入明文:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p2_plain_text = tkinter.Text(root, bd=5, width=20, height=5)
lable_p2_RSA = tkinter.Label(root, text="RSA的加密", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p2_plain_byte = tkinter.Label(root, text="1. Plain = encode(明文)", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p2_plain_byte = tkinter.Text(root, bd=5, width=40, height=4)
lable_p2_cipher_text = tkinter.Label(root, text="2. Cipher = Plain ^ E mod N", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p2_cipher_text = tkinter.Text(root, bd=5, width=40, height=4)
button_p2 = tkinter.Button(
root, text="RSA密钥加密", font=("黑体", 13), command=part2)
###################################
lable_part3 = tkinter.Label(root, text="Part③-RSA解密过程", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p3_private_key = tkinter.Label(root, text="请输入私钥{D,N}:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
entry_p3_private_key_D = tkinter.Entry(root, bd=5)
entry_p3_private_key_N = tkinter.Entry(root, bd=5)
lable_p3_cipher_text = tkinter.Label(root, text="请输入密文:", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p3_cipher_text = tkinter.Text(root, bd=5, width=20, height=5)
lable_p3_RSA = tkinter.Label(root, text="RSA的解密", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
lable_p3_plain_text = tkinter.Label(root, text="1. Plain = Cipher ^ D mod N", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p3_plain_text = tkinter.Text(root, bd=5, width=40, height=4)
lable_p3_mingwen_text = tkinter.Label(root, text="2. 明文 = decode(Plain)", font=("黑体", 13), width=25,
height=20, fg="black", bg="white")
text_p3_mingwen_text = tkinter.Text(root, bd=5, width=40, height=4)
button_p3 = tkinter.Button(
root, text="RSA密钥解密", font=("黑体", 13), command=part3)
c1 = tkinter.Canvas(bg='black', width=2, height=430)
c2 = tkinter.Canvas(bg='black', width=2, height=430)
b1 = tkinter.Canvas(bg='black', width=398, height=2)
b2 = tkinter.Canvas(bg='black', width=393, height=2)
b3 = tkinter.Canvas(bg='black', width=393, height=2)
###Part1#################################################
lable_part1.place(x=100, y=10, width=200, height=20)
lable_p1_p.place(x=20, y=50, width=150, height=20)
entry_p1_p.place(x=20, y=70)
lable_p1_q.place(x=200, y=50, width=150, height=20)
entry_p1_q.place(x=200, y=70)
lable_p1_EDN.place(x=10, y=110, width=130, height=20)
lable_p1_N.place(x=10, y=130, width=115, height=20)
text_p1_N.place(x=10, y=150)
lable_p1_L.place(x=10, y=170, width=186, height=20)
text_p1_L.place(x=10, y=190)
lable_p1_E.place(x=10, y=210, width=162, height=20)
text_p1_E.place(x=10, y=230)
lable_p1_D.place(x=10, y=250, width=200, height=20)
text_p1_D.place(x=10, y=270)
lable_p1_public_key.place(x=20, y=300, width=120, height=20)
entry_p1_public_key_E.place(x=20, y=320)
entry_p1_public_key_N.place(x=20, y=350)
lable_p1_private_key.place(x=200, y=300, width=120, height=20)
entry_p1_private_key_D.place(x=200, y=320)
entry_p1_private_key_N.place(x=200, y=350)
b1.place(x=0, y=100)
c1.place(x=400, y=0)
button_p1.place(x=140, y=390)
###Part2#################################################
lable_part2.place(x=500, y=10, width=200, height=20)
lable_p2_private_key.place(x=420, y=50, width=150, height=20)
entry_p2_public_key_E.place(x=420, y=70)
entry_p2_public_key_N.place(x=420, y=100)
lable_p2_plain_text.place(x=600, y=50, width=120, height=20)
text_p2_plain_text.place(x=600, y=70)
lable_p2_RSA.place(x=410, y=160, width=100, height=20)
lable_p2_plain_byte.place(x=410, y=180, width=210, height=20)
text_p2_plain_byte.place(x=420, y=200)
lable_p2_cipher_text.place(x=410, y=280, width=250, height=20)
text_p2_cipher_text.place(x=420, y=300)
b2.place(x=404, y=150)
c2.place(x=800, y=0)
button_p2.place(x=540, y=390)
###Part3#################################################
lable_part3.place(x=900, y=10, width=200, height=20)
lable_p3_private_key.place(x=820, y=50, width=150, height=20)
entry_p3_private_key_D.place(x=820, y=70)
entry_p3_private_key_N.place(x=820, y=100)
lable_p3_cipher_text.place(x=1000, y=50, width=120, height=20)
text_p3_cipher_text.place(x=1000, y=70)
lable_p3_RSA.place(x=810, y=160, width=100, height=20)
lable_p3_plain_text.place(x=810, y=180, width=250, height=20)
text_p3_plain_text.place(x=820, y=200)
lable_p3_mingwen_text.place(x=810, y=280, width=210, height=20)
text_p3_mingwen_text.place(x=820, y=300)
b3.place(x=804, y=150)
button_p3.place(x=940, y=390)
root.mainloop()
RSA代码部分参考自:https://blog.csdn.net/qq_36944952/article/details/103973849