You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
3.2 KiB
87 lines
3.2 KiB
import tkinter as tk
|
|
from tkinter import ttk, filedialog, messagebox
|
|
import os
|
|
|
|
from .context import UIContext
|
|
|
|
|
|
def create_keys_tab(notebook: ttk.Notebook, ctx: UIContext, crypto_mod) -> ttk.Frame:
|
|
frame = ttk.Frame(notebook)
|
|
notebook.add(frame, text="密钥/证书")
|
|
|
|
# 说明
|
|
ttk.Label(
|
|
frame,
|
|
text="说明:管理 RSA 密钥对。生成新密钥或加载已有密钥,用于数字信封的加密解密。",
|
|
wraplength=600
|
|
).pack(anchor=tk.W, padx=10, pady=10)
|
|
|
|
# 生成密钥区域
|
|
gen_frame = ttk.LabelFrame(frame, text="生成 RSA 密钥对")
|
|
gen_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
|
|
ttk.Label(gen_frame, text="用户名(用于命名密钥文件)").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
|
|
username = tk.StringVar(value="user")
|
|
ttk.Entry(gen_frame, textvariable=username, width=20).grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
|
|
|
|
ttk.Label(gen_frame, text="密钥长度(位)").grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
|
|
key_size = tk.StringVar(value="2048")
|
|
ttk.Combobox(gen_frame, textvariable=key_size, values=["2048", "4096"], state="readonly", width=10).grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)
|
|
|
|
ttk.Button(
|
|
gen_frame,
|
|
text="生成密钥对",
|
|
command=lambda: _on_generate_keypair(ctx, crypto_mod, username, key_size)
|
|
).grid(row=2, column=0, columnspan=2, padx=5, pady=10)
|
|
|
|
return frame
|
|
|
|
|
|
def _on_generate_keypair(ctx: UIContext, crypto_mod, username: tk.StringVar, key_size: tk.StringVar):
|
|
"""生成 RSA 密钥对"""
|
|
if not ctx.ensure_impl(crypto_mod, "密钥生成"):
|
|
return
|
|
|
|
try:
|
|
uname = username.get().strip()
|
|
if not uname:
|
|
messagebox.showwarning("提示", "请输入用户名")
|
|
return
|
|
|
|
ksize = int(key_size.get())
|
|
ctx.log(f"[密钥生成] 正在生成 {ksize} 位 RSA 密钥对,用户: {uname}...")
|
|
|
|
# 生成密钥对
|
|
private_key, public_key = crypto_mod.generate_rsa_keypair(ksize)
|
|
|
|
# 选择保存位置
|
|
keys_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "keys")
|
|
os.makedirs(keys_dir, exist_ok=True)
|
|
|
|
# 保存公钥
|
|
pub_path = os.path.join(keys_dir, f"{uname}_rsa_pub.pem")
|
|
crypto_mod.save_public_key_to_pem(public_key, pub_path)
|
|
ctx.log(f"[密钥生成] 公钥已保存: {pub_path}")
|
|
|
|
# 保存私钥
|
|
priv_path = os.path.join(keys_dir, f"{uname}_rsa_priv.pem")
|
|
crypto_mod.save_private_key_to_pem(private_key, priv_path, password=None)
|
|
ctx.log(f"[密钥生成] 私钥已保存: {priv_path}")
|
|
|
|
messagebox.showinfo(
|
|
"生成成功",
|
|
f"RSA 密钥对已生成!\n\n"
|
|
f"公钥: {pub_path}\n"
|
|
f"私钥: {priv_path}\n\n"
|
|
f"请将公钥发送给对方。"
|
|
)
|
|
ctx.set_status(f"已生成 {uname} 的密钥对({ksize}位)")
|
|
|
|
except Exception as e:
|
|
import traceback
|
|
ctx.log(f"[密钥生成] 失败: {e}")
|
|
ctx.log(traceback.format_exc())
|
|
messagebox.showerror("生成失败", str(e))
|
|
|
|
|