├── mypass ├── __init__.py ├── __pycache__ │ ├── getpass.cpython-310.pyc │ ├── getpass.cpython-312.pyc │ ├── __init__.cpython-310.pyc │ ├── __init__.cpython-312.pyc │ └── encryption_service.cpython-310.pyc ├── server.py ├── getpass.py ├── encryption_service.py └── client.py ├── requirements.txt ├── local_use.py ├── example.py ├── README.md └── visulization.html /mypass/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests 3 | cryptography -------------------------------------------------------------------------------- /mypass/__pycache__/getpass.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JL-ghcoder/mypass/HEAD/mypass/__pycache__/getpass.cpython-310.pyc -------------------------------------------------------------------------------- /mypass/__pycache__/getpass.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JL-ghcoder/mypass/HEAD/mypass/__pycache__/getpass.cpython-312.pyc -------------------------------------------------------------------------------- /mypass/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JL-ghcoder/mypass/HEAD/mypass/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /mypass/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JL-ghcoder/mypass/HEAD/mypass/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /mypass/__pycache__/encryption_service.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JL-ghcoder/mypass/HEAD/mypass/__pycache__/encryption_service.cpython-310.pyc -------------------------------------------------------------------------------- /local_use.py: -------------------------------------------------------------------------------- 1 | from mypass.getpass import get_password 2 | 3 | password3 = get_password( 4 | encrypted_data="", 5 | iv="", 6 | local_key="" 7 | ) 8 | 9 | print("password3: ", password3) -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | from mypass.getpass import get_password 2 | 3 | password1 = get_password( 4 | server_url="http://localhost:6666/decrypt", 5 | key_file="encrypted_key.json" 6 | ) 7 | 8 | password2 = get_password( 9 | server_url="http://localhost:6666/decrypt", 10 | encrypted_data="xxx", 11 | iv="xxx" 12 | ) 13 | 14 | password3 = get_password( 15 | encrypted_data="xxx", 16 | iv="xxx", 17 | local_key="xxx" 18 | ) 19 | 20 | print("password1: ", password1) 21 | print("password2: ", password2) 22 | print("password3: ", password3) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MyPass - 加密密码管理系统 2 | 3 | 一个终端界面的加密密码管理系统,用于安全地存储和获取敏感信息,如数据库密码、API密钥等。该系统使用AES-256-CBC加密算法,通过客户端-服务器架构提供安全的密码解密服务。 4 | 5 | 我的用法: 6 | 1. 运行encryption_service.py,设置一个解密密钥,将密码进行加密 7 | 2. 在一台服务器运行server.py,用于提供远程解密服务,并且输入正确的解密密钥进行解密 8 | 3. 在交易服务器上通过 mypass.getpass 来访问远端服务将加密的密码解密 9 | 4. 关闭 server.py 10 | 11 | 这样做可以确保全程不出现密码的明文,并且即使哪一台被黑也不会泄露出密码。 12 | 13 | 关闭解密服务后黑客只可能通过内存探针获取密码,但这基本上是不可能实现的。 14 | 15 | 即使两台服务器都被黑客同时黑掉,黑客也无法获取明文密码,并且只要解密密钥没有泄露,解密服务也无法完成解密工作。 16 | 17 | **我的建议:** 18 | 将解密用的server.py直接跑在本地而不是公网服务器,绑定cloudflare的tunnel,要进行密码验证的时候在本地运行服务并且让cloudflare广播并且接听,这样cloudflare tunnel会建立一个加密隧道,通信会在TLS层面加密,中间人攻击的风险会大幅降低。 19 | 20 | ## 安装 21 | 22 | ### 依赖项 23 | 24 | ```bash 25 | pip install flask requests cryptography 26 | ``` 27 | 28 | ## 使用方法 29 | 30 | ### 1. 加密数据 31 | 32 | 首先使用加密服务加密您的敏感数据: 33 | 34 | ```bash 35 | python encryption_service.py 36 | ``` 37 | 38 | 按照界面提示输入您的数据和加密密钥,加密结果将保存到`encrypted_key.json`文件。 39 | 40 | ### 2. 启动解密服务器 41 | 42 | 在需要提供解密服务的机器上运行: 43 | 44 | ```bash 45 | python server.py 46 | ``` 47 | 48 | 输入端口号和解密密钥(必须与加密时使用的密钥相同)。 49 | 50 | ### 3. 使用客户端解密 51 | 52 | 要手动解密数据,可以运行客户端: 53 | 54 | ```bash 55 | python client.py 56 | ``` 57 | 58 | 根据提示输入服务器URL和加密数据。 59 | 60 | ### 4. 在应用程序中使用 61 | 62 | ```python 63 | from mypass.getpass import get_password 64 | 65 | password1 = get_password( 66 | server_url="http://localhost:6666/decrypt", 67 | key_file="encrypted_key.json" 68 | ) 69 | 70 | password2 = get_password( 71 | server_url="http://localhost:6666/decrypt", 72 | encrypted_data="6BxemLxyiBXFwfMEetiXiQ==", 73 | iv="6WhgnvA+zrAEiySRSpSH6w==" 74 | ) 75 | 76 | password3 = get_password( 77 | encrypted_data="6BxemLxyiBXFwfMEetiXiQ==", 78 | iv="6WhgnvA+zrAEiySRSpSH6w==", 79 | local_key="helloworld" 80 | ) 81 | 82 | print("password1: ", password1) 83 | print("password2: ", password2) 84 | print("password3: ", password3) 85 | ``` -------------------------------------------------------------------------------- /mypass/server.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import logging 5 | import threading 6 | import time 7 | from flask import Flask, request, jsonify 8 | from encryption_service import decrypt 9 | 10 | logging.basicConfig( 11 | level=logging.INFO, 12 | format='%(asctime)s - %(levelname)s - %(message)s', 13 | handlers=[ 14 | logging.StreamHandler(sys.stdout) 15 | ] 16 | ) 17 | logger = logging.getLogger(__name__) 18 | 19 | def clear_screen(): 20 | os.system('cls' if os.name == 'nt' else 'clear') 21 | 22 | def print_banner(): 23 | banner = """ 24 | ) ( ) ( ( ) ( ( 25 | ( )\ ) ` ) ( /( ( ( ___ ( ))\ )( /(( ))\ )( 26 | )\ '(()/( /(/( )(_)) )\ )\|___|)\ /((_)(()\ (_))\ /((_)(()\ 27 | _((_)) )(_))((_)_\ ((_)_ ((_)((_) ((_)(_)) ((_)_)((_)(_)) ((_) 28 | | ' \()| || || '_ \)/ _` |(_-<(_-< (_- -_) | '_|\ V / / -_) | '_| 29 | |_|_|_| \_, || .__/ \__,_|/__//__/ /__/\___| |_| \_/ \___| |_| 30 | |__/ |_| 31 | 32 | """ 33 | print(banner) 34 | 35 | def create_server(encryption_key): 36 | """创建Flask服务器实例""" 37 | server = Flask(__name__) 38 | server.encryption_key = encryption_key 39 | 40 | log = logging.getLogger('werkzeug') 41 | log.setLevel(logging.ERROR) 42 | 43 | @server.route('/decrypt', methods=['POST']) 44 | def decrypt_key(): 45 | """处理解密请求""" 46 | try: 47 | # 从请求中获取加密的数据和IV 48 | data = request.json 49 | logger.info(f"收到解密请求") 50 | 51 | if not data or 'encrypted_data' not in data or 'iv' not in data: 52 | logger.error("请求缺少必要参数") 53 | return jsonify({"error": "缺少必要的参数"}), 400 54 | 55 | encrypted_data = data.get('encrypted_data') 56 | iv = data.get('iv') 57 | 58 | # 使用服务器的主密钥解密数据 59 | decrypted_key = decrypt(encrypted_data, server.encryption_key, iv) 60 | logger.info(f"解密成功,密码长度: {len(decrypted_key)} 字符") 61 | 62 | print(f"\n [新请求] 解密成功,密码长度: {len(decrypted_key)} 字符") 63 | 64 | # 返回解密后的密钥 65 | return jsonify({"decrypted_key": decrypted_key}) 66 | 67 | except Exception as e: 68 | logger.error(f"解密出错: {str(e)}") 69 | print(f"\n [错误] 解密失败: {str(e)}") 70 | return jsonify({"error": "解密失败"}), 500 71 | 72 | return server 73 | 74 | def run_server_thread(port, encryption_key, stop_event): 75 | """在线程中运行服务器""" 76 | server = create_server(encryption_key) 77 | 78 | from werkzeug.serving import make_server 79 | 80 | # 创建服务器 81 | srv = make_server('0.0.0.0', port, server) 82 | srv.daemon_threads = True 83 | 84 | # 设置服务器的轮询间隔 85 | srv.service_timeout = 1 86 | 87 | clear_screen() 88 | print_banner() 89 | print(f"\n 服务器已启动,监听端口: {port}") 90 | print(f" 解密密钥: {encryption_key}") 91 | print("\n [状态] 等待连接...") 92 | print("\n 按Ctrl+C停止服务器") 93 | 94 | # 运行服务器直到被停止 95 | try: 96 | while not stop_event.is_set(): 97 | srv.handle_request() 98 | except KeyboardInterrupt: 99 | pass 100 | 101 | def main(): 102 | """主函数""" 103 | clear_screen() 104 | print_banner() 105 | 106 | # 获取端口 107 | while True: 108 | try: 109 | port_str = input("\n 请输入服务器端口 (1024-65535): ") 110 | port = int(port_str) 111 | if 1024 <= port <= 65535: 112 | break 113 | print(" [错误] 端口必须在1024-65535之间") 114 | except ValueError: 115 | print(" [错误] 请输入有效的端口号") 116 | 117 | # 获取解密密钥 118 | while True: 119 | encryption_key = input("\n 请输入解密密钥: ") 120 | if encryption_key: 121 | break 122 | print(" [错误] 密钥不能为空") 123 | 124 | # 创建停止事件 125 | stop_event = threading.Event() 126 | 127 | try: 128 | # 运行服务器 129 | run_server_thread(port, encryption_key, stop_event) 130 | except KeyboardInterrupt: 131 | 132 | stop_event.set() 133 | print("\n\n 正在停止服务器...") 134 | time.sleep(1) 135 | print(" 服务器已停止") 136 | 137 | print("\n 感谢使用解密服务器!") 138 | 139 | if __name__ == "__main__": 140 | try: 141 | main() 142 | except KeyboardInterrupt: 143 | print("\n\n 操作已取消") 144 | print(" 感谢使用解密服务器!") -------------------------------------------------------------------------------- /mypass/getpass.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import requests 4 | import base64 5 | import hashlib 6 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 7 | from cryptography.hazmat.backends import default_backend 8 | 9 | DEFAULT_SERVER_URL = "http://localhost:6666/decrypt" 10 | DEFAULT_KEY_FILE = os.path.join(os.path.dirname(__file__), 'encrypted_key.json') 11 | 12 | def load_encrypted_key(filepath=None): 13 | """ 14 | 从文件加载加密后的密钥 15 | 16 | Args: 17 | filepath (str, optional): 加密密钥文件路径 18 | 19 | Returns: 20 | dict: 包含encrypted_data和iv的字典,如果加载失败则返回None 21 | """ 22 | try: 23 | 24 | if filepath is None: 25 | filepath = DEFAULT_KEY_FILE 26 | 27 | if not os.path.exists(filepath): 28 | print(f"错误: 加密密钥文件不存在: {filepath}") 29 | return None 30 | 31 | with open(filepath, 'r') as f: 32 | return json.load(f) 33 | except Exception as e: 34 | print(f"错误: 无法加载加密密钥文件: {str(e)}") 35 | return None 36 | 37 | def decrypt_locally(encrypted_data_b64, key, iv_b64): 38 | """ 39 | 在本地使用提供的密钥解密数据 40 | 41 | Args: 42 | encrypted_data_b64 (str): Base64编码的加密数据 43 | key (str): 解密密钥 44 | iv_b64 (str): Base64编码的初始化向量 45 | 46 | Returns: 47 | str: 解密后的原始数据,如果解密失败则返回None 48 | """ 49 | try: 50 | 51 | key_hash = hashlib.sha256(key.encode()).digest() 52 | 53 | iv = base64.b64decode(iv_b64) 54 | encrypted_data = base64.b64decode(encrypted_data_b64) 55 | 56 | cipher = Cipher( 57 | algorithms.AES(key_hash), 58 | modes.CBC(iv), 59 | backend=default_backend() 60 | ) 61 | decryptor = cipher.decryptor() 62 | 63 | padded_data = decryptor.update(encrypted_data) + decryptor.finalize() 64 | 65 | pad_length = padded_data[-1] 66 | data = padded_data[:-pad_length] 67 | 68 | return data.decode('utf-8') 69 | except Exception as e: 70 | print(f"错误: 本地解密失败: {str(e)}") 71 | return None 72 | 73 | def request_remote_decryption(server_url, encrypted_data, iv): 74 | """ 75 | 向远程服务器请求解密 76 | 77 | Args: 78 | server_url (str): 服务器URL 79 | encrypted_data (str): 加密后的数据 80 | iv (str): 初始化向量 81 | 82 | Returns: 83 | str: 解密后的密钥,如果解密失败则返回None 84 | """ 85 | try: 86 | 87 | data = { 88 | "encrypted_data": encrypted_data, 89 | "iv": iv 90 | } 91 | 92 | response = requests.post(server_url, json=data, timeout=10) 93 | 94 | if response.status_code == 200: 95 | return response.json().get("decrypted_key") 96 | else: 97 | error_msg = response.json().get("error", f"服务器返回错误代码: {response.status_code}") 98 | print(f"错误: {error_msg}") 99 | return None 100 | 101 | except requests.exceptions.RequestException as e: 102 | print(f"错误: 请求失败 - {str(e)}") 103 | return None 104 | except Exception as e: 105 | print(f"错误: {str(e)}") 106 | return None 107 | 108 | def get_password(server_url=None, encrypted_data=None, iv=None, key_file=None, local_key=None): 109 | """ 110 | 获取解密后的密码 111 | 112 | 可以通过以下几种方式使用: 113 | 1. 提供server_url、encrypted_data和iv直接请求解密 114 | 2. 提供key_file从文件加载加密数据并请求解密 115 | 3. 提供local_key、encrypted_data和iv在本地解密 116 | 117 | Args: 118 | server_url (str, optional): 解密服务器URL 119 | encrypted_data (str, optional): 加密后的数据 120 | iv (str, optional): 初始化向量 121 | key_file (str, optional): 加密密钥文件路径 122 | local_key (str, optional): 本地解密密钥 123 | 124 | Returns: 125 | str: 解密后的密码,如果解密失败则返回None 126 | """ 127 | 128 | if server_url is None: 129 | server_url = DEFAULT_SERVER_URL 130 | 131 | if encrypted_data is None or iv is None: 132 | encrypted_key = load_encrypted_key(key_file) 133 | if encrypted_key is None: 134 | return None 135 | 136 | encrypted_data = encrypted_key.get("encrypted_data") 137 | iv = encrypted_key.get("iv") 138 | 139 | if encrypted_data is None or iv is None: 140 | print("错误: 缺少必要的加密数据或初始化向量") 141 | return None 142 | 143 | if local_key is not None: 144 | password = decrypt_locally(encrypted_data, local_key, iv) 145 | if password is not None: 146 | return password 147 | # 如果本地解密失败,尝试远程解密 148 | 149 | # 请求远程解密 150 | return request_remote_decryption(server_url, encrypted_data, iv) 151 | 152 | 153 | # 方法1: 使用默认配置从文件加载 154 | # password = get_password() 155 | # if password: 156 | # print(f"解密后的密码: {password}") 157 | 158 | # 方法2: 指定文件路径 159 | # password = get_password(key_file="/path/to/my/encrypted_key.json") 160 | 161 | # 方法3: 指定加密数据和初始化向量 162 | # password = get_password( 163 | # encrypted_data="WFsEHALbpAq1w3emXUBICw==", 164 | # iv="NxBiKQPUN+Bm+iA/8mj0Zg==" 165 | # ) 166 | 167 | # 方法4: 使用本地密钥解密 168 | # password = get_password( 169 | # encrypted_data="WFsEHALbpAq1w3emXUBICw==", 170 | # iv="NxBiKQPUN+Bm+iA/8mj0Zg==", 171 | # local_key="happy" 172 | # ) -------------------------------------------------------------------------------- /mypass/encryption_service.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hashlib 3 | import os 4 | import json 5 | import sys 6 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 7 | from cryptography.hazmat.backends import default_backend 8 | 9 | DEFAULT_ENCRYPTED_KEY_FILE = os.path.join(os.path.dirname(__file__), 'encrypted_key.json') 10 | 11 | def encrypt(data, key): 12 | """ 13 | 使用提供的密钥加密数据 14 | 15 | Args: 16 | data (str): 要加密的数据 17 | key (str): 加密密钥 18 | 19 | Returns: 20 | dict: 包含加密后的数据和初始化向量 21 | """ 22 | # 创建一个32位的密钥 (使用SHA-256哈希密钥) 23 | key_hash = hashlib.sha256(key.encode()).digest() 24 | 25 | # 生成随机初始化向量 26 | iv = os.urandom(16) 27 | 28 | # 创建加密器 29 | cipher = Cipher( 30 | algorithms.AES(key_hash), 31 | modes.CBC(iv), 32 | backend=default_backend() 33 | ) 34 | encryptor = cipher.encryptor() 35 | 36 | # 填充数据为16字节的倍数 (AES块大小) 37 | pad_length = 16 - (len(data.encode()) % 16) 38 | padded_data = data.encode() + bytes([pad_length]) * pad_length 39 | 40 | # 加密数据 41 | encrypted_data = encryptor.update(padded_data) + encryptor.finalize() 42 | 43 | return { 44 | "encrypted_data": base64.b64encode(encrypted_data).decode('utf-8'), 45 | "iv": base64.b64encode(iv).decode('utf-8') 46 | } 47 | 48 | def decrypt(encrypted_data_b64, key, iv_b64): 49 | """ 50 | 使用提供的密钥解密数据 51 | 52 | Args: 53 | encrypted_data_b64 (str): Base64编码的加密数据 54 | key (str): 解密密钥 55 | iv_b64 (str): Base64编码的初始化向量 56 | 57 | Returns: 58 | str: 解密后的原始数据 59 | """ 60 | # 创建一个32位的密钥 (使用SHA-256哈希密钥) 61 | key_hash = hashlib.sha256(key.encode()).digest() 62 | 63 | # 将IV和加密数据从Base64解码 64 | iv = base64.b64decode(iv_b64) 65 | encrypted_data = base64.b64decode(encrypted_data_b64) 66 | 67 | cipher = Cipher( 68 | algorithms.AES(key_hash), 69 | modes.CBC(iv), 70 | backend=default_backend() 71 | ) 72 | decryptor = cipher.decryptor() 73 | 74 | padded_data = decryptor.update(encrypted_data) + decryptor.finalize() 75 | 76 | pad_length = padded_data[-1] 77 | data = padded_data[:-pad_length] 78 | 79 | return data.decode('utf-8') 80 | 81 | def save_encrypted_data(data, filepath=DEFAULT_ENCRYPTED_KEY_FILE): 82 | """ 83 | 保存加密数据到文件 84 | 85 | Args: 86 | data (dict): 包含encrypted_data和iv的字典 87 | filepath (str): 保存的文件路径 88 | 89 | Returns: 90 | bool: 保存是否成功 91 | """ 92 | try: 93 | with open(filepath, 'w') as f: 94 | json.dump(data, f, indent=2) 95 | return True 96 | except Exception as e: 97 | print(f" [错误] 保存文件失败: {str(e)}") 98 | return False 99 | 100 | def clear_screen(): 101 | os.system('cls' if os.name == 'nt' else 'clear') 102 | 103 | def print_banner(): 104 | banner = """ 105 | __ __ _ _ ____ __ ___ ___ ____ _____ _____ __ 106 | ( \/ )( \/ )( _ \ /__\ / __)/ __) ___(_ _)( _ )( _ )( ) 107 | ) ( \ / )___//(__)\ \__ \\__ \(___) )( )(_)( )(_)( )(__ 108 | (_/\/\_) (__) (__) (__)(__)(___/(___/ (__) (_____)(_____)(____) 109 | """ 110 | print(banner) 111 | 112 | def print_menu(): 113 | 114 | menu = """ 115 | 请选择操作: 116 | 1. 加密数据 117 | 2. 退出 118 | 119 | 选择: """ 120 | return input(menu) 121 | 122 | def get_input(prompt): 123 | """获取用户输入""" 124 | return input(prompt) 125 | 126 | def main(): 127 | 128 | while True: 129 | clear_screen() 130 | print_banner() 131 | choice = print_menu() 132 | 133 | if choice == '1': 134 | clear_screen() 135 | print_banner() 136 | print("\n === 加密数据 ===\n") 137 | 138 | # 获取数据和密钥 139 | data = get_input(" 请输入要加密的数据: ") 140 | if not data: 141 | print("\n [错误] 数据不能为空!") 142 | input("\n 按回车键继续...") 143 | continue 144 | 145 | key = get_input(" 请输入加密密钥: ") 146 | if not key: 147 | print("\n [错误] 密钥不能为空!") 148 | input("\n 按回车键继续...") 149 | continue 150 | 151 | # 执行加密 152 | try: 153 | result = encrypt(data, key) 154 | 155 | print("\n === 加密结果 ===\n") 156 | print(f" 加密数据: {result['encrypted_data']}") 157 | print(f" 初始化向量(IV): {result['iv']}") 158 | 159 | json_result = json.dumps(result, indent=4) 160 | print("\n JSON格式:") 161 | print(f" {json_result.replace(chr(10), chr(10)+' ')}") 162 | 163 | # 保存到文件 164 | save_successful = save_encrypted_data(result) 165 | if save_successful: 166 | print(f"\n 加密结果已保存到文件: {DEFAULT_ENCRYPTED_KEY_FILE}") 167 | 168 | print("\n 加密成功!") 169 | except Exception as e: 170 | print(f"\n [错误] 加密失败: {str(e)}") 171 | 172 | input("\n 按回车键继续...") 173 | 174 | elif choice == '2': 175 | print("\n 感谢使用加密工具!") 176 | break 177 | 178 | else: 179 | print("\n [错误] 无效的选择!") 180 | input("\n 按回车键继续...") 181 | 182 | if __name__ == "__main__": 183 | main() -------------------------------------------------------------------------------- /mypass/client.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import requests 5 | 6 | def clear_screen(): 7 | os.system('cls' if os.name == 'nt' else 'clear') 8 | 9 | def print_banner(): 10 | banner = """ 11 | ( ) 12 | ) ( ) )\ ( ( ( /( 13 | ( )\ ) ` ) ( /( ( ( ___ ( ((_))\ ))\ ( )\()) 14 | )\ '(()/( /(/( )(_)) )\ )\|___|)\ _ ((_) /((_) )\ ) (_))/ 15 | _((_)) )(_))((_)_\ ((_)_ ((_)((_) ((_)| | (_)(_)) _(_/( | |_ 16 | | ' \()| || || '_ \)/ _` |(_-<(_-< / _| | | | |/ -_)| ' \))| _| 17 | |_|_|_| \_, || .__/ \__,_|/__//__/ \__| |_| |_|\___||_||_| \__| 18 | |__/ |_| 19 | 20 | """ 21 | print(banner) 22 | 23 | def print_menu(): 24 | 25 | menu = """ 26 | 请选择操作: 27 | 1. 输入加密数据并解密 28 | 2. 输入JSON格式的加密数据并解密 29 | 3. 退出 30 | 31 | 选择: """ 32 | return input(menu) 33 | 34 | def get_input(prompt): 35 | 36 | return input(prompt) 37 | 38 | def request_decryption(server_url, encrypted_data, iv): 39 | """ 40 | 向远程服务器请求解密密钥 41 | 42 | Args: 43 | server_url (str): 服务器URL 44 | encrypted_data (str): 加密后的数据 45 | iv (str): 初始化向量 46 | 47 | Returns: 48 | str: 解密后的密钥或错误信息 49 | """ 50 | try: 51 | # 准备请求数据 52 | data = { 53 | "encrypted_data": encrypted_data, 54 | "iv": iv 55 | } 56 | 57 | print("\n 正在向服务器发送解密请求...\n") 58 | 59 | response = requests.post(server_url, json=data, timeout=10) 60 | 61 | if response.status_code == 200: 62 | return response.json().get("decrypted_key", "未知响应") 63 | else: 64 | error_msg = response.json().get("error", f"服务器返回错误代码: {response.status_code}") 65 | return f"错误: {error_msg}" 66 | 67 | except requests.exceptions.RequestException as e: 68 | return f"错误: 请求失败 - {str(e)}" 69 | except Exception as e: 70 | return f"错误: {str(e)}" 71 | 72 | def decrypt_from_input(): 73 | """从用户输入解密数据""" 74 | clear_screen() 75 | print_banner() 76 | print("\n === 输入加密数据 ===\n") 77 | 78 | # 获取服务器URL 79 | server_url = get_input(" 请输入服务器URL (默认: http://localhost:6666/decrypt): ") 80 | if not server_url: 81 | server_url = "http://localhost:6666/decrypt" 82 | 83 | # 获取加密数据 84 | encrypted_data = get_input(" 请输入加密数据: ") 85 | if not encrypted_data: 86 | print("\n [错误] 加密数据不能为空!") 87 | input("\n 按回车键继续...") 88 | return 89 | 90 | # 获取IV 91 | iv = get_input(" 请输入初始化向量(IV): ") 92 | if not iv: 93 | print("\n [错误] 初始化向量不能为空!") 94 | input("\n 按回车键继续...") 95 | return 96 | 97 | result = request_decryption(server_url, encrypted_data, iv) 98 | 99 | print("\n === 解密结果 ===\n") 100 | 101 | if result.startswith("错误"): 102 | print(f" {result}") 103 | else: 104 | print(f" 解密后的密钥: {result}") 105 | 106 | input("\n 按回车键继续...") 107 | 108 | def decrypt_from_json(): 109 | """从JSON解密数据""" 110 | clear_screen() 111 | print_banner() 112 | print("\n === 输入JSON格式的加密数据 ===\n") 113 | 114 | # 获取服务器URL 115 | server_url = get_input(" 请输入服务器URL (默认: http://localhost:6666/decrypt): ") 116 | if not server_url: 117 | server_url = "http://localhost:6666/decrypt" 118 | 119 | # 获取JSON数据 120 | print("\n 请输入JSON数据 (格式: {\"encrypted_data\": \"...\", \"iv\": \"...\"})") 121 | print(" 输入完成后请按回车键两次:\n") 122 | 123 | lines = [] 124 | while True: 125 | line = input(" ") 126 | if not line and lines and lines[-1] == "": 127 | break 128 | lines.append(line) 129 | 130 | json_text = "\n".join(lines).strip() 131 | 132 | if not json_text: 133 | print("\n [错误] JSON数据不能为空!") 134 | input("\n 按回车键继续...") 135 | return 136 | 137 | try: 138 | 139 | data = json.loads(json_text) 140 | 141 | if "encrypted_data" not in data or "iv" not in data: 142 | print("\n [错误] JSON必须包含'encrypted_data'和'iv'字段!") 143 | input("\n 按回车键继续...") 144 | return 145 | 146 | encrypted_data = data["encrypted_data"] 147 | iv = data["iv"] 148 | 149 | # 请求解密 150 | result = request_decryption(server_url, encrypted_data, iv) 151 | 152 | print("\n === 解密结果 ===\n") 153 | 154 | if result.startswith("错误"): 155 | print(f" {result}") 156 | else: 157 | print(f" 解密后的密钥: {result}") 158 | 159 | except json.JSONDecodeError: 160 | print("\n [错误] 无效的JSON格式!") 161 | except Exception as e: 162 | print(f"\n [错误] {str(e)}") 163 | 164 | input("\n 按回车键继续...") 165 | 166 | def main(): 167 | 168 | while True: 169 | clear_screen() 170 | print_banner() 171 | choice = print_menu() 172 | 173 | if choice == '1': 174 | decrypt_from_input() 175 | 176 | elif choice == '2': 177 | decrypt_from_json() 178 | 179 | elif choice == '3': 180 | print("\n 感谢使用解密客户端!") 181 | break 182 | 183 | else: 184 | print("\n [错误] 无效的选择!") 185 | input("\n 按回车键继续...") 186 | 187 | if __name__ == "__main__": 188 | try: 189 | main() 190 | except KeyboardInterrupt: 191 | print("\n\n 操作已取消") 192 | print(" 感谢使用解密客户端!") -------------------------------------------------------------------------------- /visulization.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |13 | __ __ _ _ ____ __ ___ ___ ____ _____ _____ __ 14 | ( \/ )( \/ )( _ \ /__\ / __)/ __) ___(_ _)( _ )( _ )( ) 15 | ) ( \ / )___//(__)\ \__ \\__ \(___) )( )(_)( )(_)( )(__ 16 | (_/\/\_) (__) (__) (__)(__)(___/(___/ (__) (_____)(_____)(____) 17 |18 |