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

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))