117 lines
3.8 KiB
Python
117 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Config Decryptor Tool
|
||
|
||
读取加密后的配置文件(Base64 + DES-CBC),还原为原始 JSON 配置。
|
||
"""
|
||
|
||
import json
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from rich.console import Console
|
||
from rich.panel import Panel
|
||
from rich.syntax import Syntax
|
||
|
||
# Add the src directory to the path so we can import the crypto module
|
||
sys.path.insert(0, str(Path(__file__).parent / "src"))
|
||
|
||
from config_man.utils.crypto import decrypt
|
||
|
||
# Initialize rich console
|
||
console = Console()
|
||
|
||
|
||
def load_encrypted_file(file_path):
|
||
"""Load encrypted file content as a single string (strip whitespace)."""
|
||
try:
|
||
with open(file_path, "r", encoding="utf-8") as f:
|
||
content = f.read().strip()
|
||
if not content:
|
||
console.print(f"[red]错误: 文件 {file_path} 为空[/red]")
|
||
return None
|
||
return content
|
||
except FileNotFoundError:
|
||
console.print(f"[red]错误: 文件 {file_path} 不存在[/red]")
|
||
return None
|
||
except Exception as e:
|
||
console.print(f"[red]错误: 无法读取文件 {file_path}: {str(e)}[/red]")
|
||
return None
|
||
|
||
|
||
def decrypt_to_config(encrypted_content):
|
||
"""Decrypt and parse JSON into a Python object."""
|
||
try:
|
||
plain = decrypt(encrypted_content)
|
||
return json.loads(plain)
|
||
except json.JSONDecodeError as e:
|
||
console.print(f"[red]错误: 解密后内容不是有效 JSON: {str(e)}[/red]")
|
||
return None
|
||
except Exception as e:
|
||
console.print(f"[red]错误: 解密失败: {str(e)}[/red]")
|
||
return None
|
||
|
||
|
||
def save_raw_config(config_data, file_path):
|
||
"""Save decrypted config as formatted JSON."""
|
||
try:
|
||
with open(file_path, "w", encoding="utf-8") as f:
|
||
json.dump(config_data, f, ensure_ascii=False, indent=2)
|
||
console.print(f"[green]✅ 解密后的配置文件已保存到: {file_path}[/green]")
|
||
return True
|
||
except Exception as e:
|
||
console.print(f"[red]错误: 无法保存文件 {file_path}: {str(e)}[/red]")
|
||
return False
|
||
|
||
|
||
def main():
|
||
console.print(Panel("🔓 Config Decryptor Tool", expand=False, border_style="bold blue"))
|
||
|
||
while True:
|
||
input_file = input("请输入要解密的配置文件路径 (如: encrypted_config.json): ").strip()
|
||
if input_file and os.path.exists(input_file):
|
||
break
|
||
console.print("[red]❌ 文件不存在,请重新输入[/red]")
|
||
|
||
console.print(f"[blue]正在读取加密文件: {input_file}[/blue]")
|
||
encrypted_blob = load_encrypted_file(input_file)
|
||
if encrypted_blob is None:
|
||
return 1
|
||
|
||
console.print("[blue]正在解密…[/blue]")
|
||
config_data = decrypt_to_config(encrypted_blob)
|
||
if config_data is None:
|
||
return 1
|
||
|
||
console.print("[green]✅ 解密成功[/green]")
|
||
console.print(Panel("解密后的配置内容", title="📄 原始配置", border_style="cyan"))
|
||
console.print(Syntax(json.dumps(config_data, ensure_ascii=False, indent=2), "json", theme="monokai"))
|
||
|
||
base = os.path.basename(input_file)
|
||
if base.startswith("encrypted_"):
|
||
default_output = "decrypted_" + base[len("encrypted_"):]
|
||
else:
|
||
default_output = "decrypted_" + base
|
||
|
||
output_file = input(f"\n请输入输出文件路径 (默认: {default_output}): ").strip()
|
||
if not output_file:
|
||
output_file = default_output
|
||
|
||
console.print(f"[blue]正在保存: {output_file}[/blue]")
|
||
if save_raw_config(config_data, output_file):
|
||
console.print(Panel("🎉 配置文件解密完成!", expand=False, border_style="bold green"))
|
||
return 0
|
||
return 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
sys.exit(main())
|
||
except KeyboardInterrupt:
|
||
print("\n\n👋 已取消操作")
|
||
sys.exit(0)
|
||
except Exception as e:
|
||
print(f"\n❌ 程序执行出错: {str(e)}")
|
||
sys.exit(1)
|