背景介绍
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
由于学校作业的契机,写一一个关于RSA密钥生成、加解密的小代码,分享给大家一同学习。
其中运用了GUI交互库tkinter,这也是我第一次使用,感觉很有意思。希望在以后的日子里可以熟练掌握这个基本python库!
代码分享
import tkinter as tk
import math
from tkinter import messagebox
import randomclass RSAApp:#构造函数,初始化def __init__(self, root):self.root = rootself.root.title("RSA 加解密")self.main_menu()def main_menu(self):#主菜单self.clear_frame()tk.Label(self.root, text="主菜单").pack(pady=10)tk.Button(self.root, text="加密", command=self.encrypt_menu).pack(pady=5)tk.Button(self.root, text="解密", command=self.decrypt_menu).pack(pady=5)tk.Button(self.root, text="生成密钥", command=self.generate_keys_menu).pack(pady=5)def encrypt_menu(self):self.clear_frame()tk.Label(self.root, text="输入明文").pack(pady=5)self.plaintext_entry = tk.Entry(self.root, width=50)self.plaintext_entry.pack(pady=5)tk.Label(self.root, text="输入公钥 (e, n)").pack(pady=5)self.public_key_entry = tk.Entry(self.root, width=50)self.public_key_entry.pack(pady=5)tk.Button(self.root, text="加密", command=self.encrypt).pack(pady=5)tk.Button(self.root, text="返回", command=self.main_menu).pack(pady=5)def decrypt_menu(self):self.clear_frame()tk.Label(self.root, text="输入密文").pack(pady=5)self.ciphertext_entry = tk.Entry(self.root, width=50)self.ciphertext_entry.pack(pady=5)tk.Label(self.root, text="输入私钥 (d, n)").pack(pady=5)self.private_key_entry = tk.Entry(self.root, width=50)self.private_key_entry.pack(pady=5)tk.Button(self.root, text="解密", command=self.decrypt).pack(pady=5)tk.Button(self.root, text="返回", command=self.main_menu).pack(pady=5)def generate_keys_menu(self):self.clear_frame()tk.Label(self.root, text="生成的密钥对").pack(pady=5)tk.Label(self.root, text="公钥 (e, n)").pack(pady=5)self.public_key_text = tk.Text(self.root, height=5, width=50)self.public_key_text.pack(pady=5)tk.Label(self.root, text="私钥 (d, n)").pack(pady=5)self.private_key_text = tk.Text(self.root, height=5, width=50)self.private_key_text.pack(pady=5)tk.Button(self.root, text="生成密钥", command=self.generate_keys).pack(pady=5)tk.Button(self.root, text="返回", command=self.main_menu).pack(pady=5)def encrypt(self):try:plaintext = int(self.plaintext_entry.get())e, n = map(int, self.public_key_entry.get().split(','))ciphertext = pow(plaintext, e, n)messagebox.showinfo("加密结果", f"密文: {ciphertext}")except Exception as e:messagebox.showerror("错误", str(e))def decrypt(self):try:ciphertext = int(self.ciphertext_entry.get())d, n = map(int, self.private_key_entry.get().split(','))plaintext = pow(ciphertext, d, n)messagebox.showinfo("解密结果", f"明文: {plaintext}")except Exception as e:messagebox.showerror("错误", str(e))def generate_keys(self):p = self.generate_prime()#生成素数q = self.generate_prime()n = p * qphi = (p - 1) * (q - 1)e=random.choice([65557,65587,65609,65617,65629,65647,65651,65657,65677,65687,65701,65707,65713,65717,65719,65729,65731,65761,65777,65789]) #公钥指数d = self.modinv(e, phi)self.public_key_text.delete(1.0, tk.END)self.private_key_text.delete(1.0, tk.END)self.public_key_text.insert(tk.END, f"{e}, {n}")self.private_key_text.insert(tk.END, f"{d}, {n}")def generate_prime(self):while True:num = random.randint(100, 999)if self.is_prime(num):return numdef is_prime(self, num):if num < 2:return Falsefor i in range(2, int(num ** 0.5) + 1):if num % i == 0:return Falsereturn Truedef modinv(self, a, m):# 扩展欧几里得算法求模逆m0, x0, x1 = m, 0, 1if m == 1:return 0while a > 1:q = a // mm, a = a % m, mx0, x1 = x1 - q * x0, x0if x1 < 0:x1 += m0return x1def clear_frame(self):for widget in self.root.winfo_children():widget.destroy()if __name__ == "__main__":root = tk.Tk() #创建主窗口对象app = RSAApp(root) #构造实例root.mainloop()
结果示范
密钥生成
加密
解密