tui: 菜单 8 密钥导入 (红色警告+二次确认+自动备份 keyring.json.bak+格式校验)

This commit is contained in:
lou
2026-08-10 15:02:51 +08:00
parent c22cbae188
commit 2535408820
+55
View File
@@ -222,6 +222,58 @@ def export_key() -> None:
print("[提示] 新设备导入: 将该文件覆盖到客户端 config/keyring.json 即可")
def import_key() -> None:
"""密钥导入: 红色风险警告 + 二次确认 + 自动备份现有密钥库"""
print("--- 密钥导入 ---")
src = _clean(input("密钥文件路径: "))
if not src or not os.path.exists(src):
print("[错误] 文件不存在")
return
try:
with open(src, encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, dict) or not data:
print("[错误] 不是有效的密钥库文件 (期望 {key_id: hex})")
return
for kid, val in data.items():
if not isinstance(val, str) or len(val) != 64:
print(f"[错误] 密钥 {kid} 格式非法 (期望 32 字节 hex)")
return
except (OSError, ValueError) as e:
print(f"[错误] 无法读取密钥文件: {e}")
return
keyring = Path(f"{CLIENT_DIR}/config/keyring.json")
print()
print("\033[91m" + "" * 52 + "\033[0m")
print("\033[91m ⚠ 危险操作警告\033[0m")
print()
print("\033[91m 导入将替换当前密钥库!\033[0m")
print("\033[91m · 现有密钥加密的密文, 导入后可能无法解密\033[0m")
print("\033[91m · 除非你确认此文件就是你要用的密钥\033[0m")
print("\033[91m · 导入前会自动备份当前密钥 -> keyring.json.bak\033[0m")
print("\033[91m · 备份文件请勿删除, 出错可手动恢复\033[0m")
print("\033[91m" + "" * 52 + "\033[0m")
print()
c1 = input("是否了解风险并继续? (输入 yes 继续): ").strip().lower()
if c1 != "yes":
print("[取消] 未导入")
return
c2 = input("再次确认: 输入 CONFIRM 才执行导入: ").strip()
if c2 != "CONFIRM":
print("[取消] 未导入")
return
# 备份现有密钥库 -> keyring.json.bak (防手滑可回滚)
if keyring.exists():
shutil.copy2(keyring, str(keyring) + ".bak")
print(f"[备份] 现有密钥已备份 -> config/keyring.json.bak")
shutil.copy2(src, keyring)
os.chmod(keyring, 0o600)
print(f"[完成] 密钥已导入 (来自 {src}, 权限 600)")
print("[提示] 导入后即可解密该密钥加密的密文; 出错可恢复 keyring.json.bak")
def main() -> int:
print("7z-encrypt 客户端 (Python TUI)")
print("安全文件传输 · 加密 / 分卷 / 上传")
@@ -235,6 +287,7 @@ def main() -> int:
print(" 5. 下载文件")
print(" 6. 删除文件")
print(" 7. 密钥导出")
print(" 8. 密钥导入")
print(" q. 退出")
choice = input("> ").strip().lower()
if choice == "1":
@@ -254,6 +307,8 @@ def main() -> int:
delete_file()
elif choice == "7":
export_key()
elif choice == "8":
import_key()
elif choice == "q":
print("再见")
return 0