4 Commits
Author SHA1 Message Date
dvs bad851f741 更新 chaoscrypt.py 2026-08-28 00:55:02 +00:00
dvs b311483963 更新 README.md 2026-08-28 00:53:38 +00:00
dvs ef90efd199 revert 587ef2140b
revert 删除 .gitignore
2026-08-28 00:51:40 +00:00
dvs 587ef2140b 删除 .gitignore 2026-08-27 10:46:24 +00:00
2 changed files with 618 additions and 504 deletions
+274 -272
View File
@@ -1,345 +1,347 @@
# 🔐 ChaosCrypt - 混沌加密系统(v2.0)
**一个完全自主设计的、抗量子、抗数学攻击的对称加密系统** # 🔐 ChaosCrypt - Chaos Encryption System (v2.0)
*不依赖 NIST、不依赖椭圆曲线、不依赖质数分解——只依赖随机性本身* **A fully self-designed, quantum-resistant, math-attack-resistant symmetric encryption system**
**v2.0 新增 💬 ChaosCryptChat:基于混沌加密的端到端加密聊天系统(文本/图片/文件/语音)** *No NIST, no elliptic curves, no prime factorization—only randomness itself*
**v2.0 New Addition 💬 ChaosCryptChat: End-to-end encrypted chat system (text/images/files/voice) built on ChaosCrypt**
--- ---
## 📖 目录 ## 📖 Table of Contents
1. [项目简介](#项目简介) 1. [Project Overview](#project-overview)
2. [设计哲学](#设计哲学) 2. [Design Philosophy](#design-philosophy)
3. [核心特性](#核心特性) 3. [Core Features](#core-features)
4. [加密流程详解](#加密流程详解) 4. [Encryption Workflow](#encryption-workflow)
5. [安全性分析](#安全性分析) 5. [Security Analysis](#security-analysis)
6. [为什么这玩意儿真的安全?(不服来辩版)](#为什么这玩意儿真的安全不服来辩版) 6. [Why This Is Actually Secure (No-BS Edition)](#why-this-is-actually-secure-no-bs-edition)
7. [快速开始](#快速开始) 7. [Quick Start](#quick-start)
8. [使用指南](#使用指南) 8. [Usage Guide](#usage-guide)
9. [API 参考](#api-参考) 9. [API Reference](#api-reference)
10. [常见问题](#常见问题) 10. [FAQ](#faq)
11. [💬 ChaosCryptChat 混沌加密聊天](#-chaoscryptchat-混沌加密聊天) 11. [💬 ChaosCryptChat](#-chaoscryptchat-chaos-encrypted-chat)
12. [项目结构](#项目结构) 12. [Project Structure](#project-structure)
13. [免责声明](#免责声明) 13. [Disclaimer](#disclaimer)
--- ---
## 项目简介 ## Project Overview
**ChaosCrypt** 是一个完全自主设计的对称加密系统。它不依赖任何第三方加密库(仅使用 `base64` 做数据编码),全部加密逻辑均为原创。 **ChaosCrypt** is a fully self-designed symmetric encryption system. It relies on no third-party crypto libraries (only `base64` for encoding)—all encryption logic is original.
**核心思想**:用**随机性**替代**数学结构**,用**多层乱序**替代**代数方程**,用**超大密钥空间**彻底扼杀暴力破解。 **Core idea**: Replace **mathematical structure** with **randomness**, replace **algebraic equations** with **multi-layer obfuscation**, and use an **immense key space** to completely shut down brute force.
> 这不是对现有加密算法的改进,而是对"安全"这个概念的重新定义。 > This is not an improvement on existing algorithms—it's a redefinition of what "secure" means.
**v2.0 新增**:在混沌加密内核之上构建了 **ChaosCryptChat** 端到端加密聊天系统,让混沌加密真正走进实时通信场景。 **v2.0 New**: Built **ChaosCryptChat**, an end-to-end encrypted chat system on top of the ChaosCrypt kernel, bringing chaos encryption to real-time communication.
--- ---
## 设计哲学 ## Design Philosophy
当今加密世界有一个默认共识:**"只有 NIST 认证的、数学优美的、学术界验证过的算法才算安全"**。 There's a consensus in the crypto world: *"Only NIST-certified, mathematically elegant, academically vetted algorithms are secure."*
ChaosCrypt 对此表示: ChaosCrypt says:
> **"你们说的都对,但我不信。"** > **"You're not wrong, but I don't buy it."**
- **Dual_EC_DRBG** 事件还历历在目——NIST 标准,NSA 后门,全世界被蒙在鼓里好几年。 - **Dual_EC_DRBG** is still fresh—NIST standard, NSA backdoor, the whole world fooled for years.
- **RSA** 数学优美吧?标准吧?**Shor 一来直接秒死。** - **RSA** is mathematically beautiful, right? Standard, right? **Shor kills it instantly.**
- **AES** 结构清晰吧?S-Box 有理有据吧?**Grover 直接给你开根号加速。** - **AES** has a clean structure, a well-reasoned S-Box, right? **Grover gives you a square-root speedup.**
**ChaosCrypt 选择另一条路:** **ChaosCrypt takes another path:**
> **不要数学结构,不要可解释性,不要任何人给你背书。** > **No math structure. No explainability. No one's stamp of approval.**
> **你唯一能做的只有暴力枚举——而枚举空间大到宇宙都装不下。** > **Your only move is brute force—and the space is so large the universe can't hold it.**
--- ---
## 核心特性 ## Core Features
| 特性 | 说明 | | Feature | Description |
|------|------| |---------|-------------|
| 🔑 **双因素保护** | 系统密钥文件 (`.key`) + 用户密码 | | 🔑 **Two-factor protection** | System key file (`.key`) + user password |
| 🧩 **完全随机密钥** | 替换表、翻转模式、长密钥、短密钥全部随机生成 | | 🧩 **Fully random keys** | Substitution tables, flip patterns, long key, short key all randomly generated |
| 📁 **密钥持久化** | 密钥文件经过混淆存储(Base64 + 反转 + 移位),防止直接读取 | | 📁 **Key persistence** | Keys stored obfuscated (Base64 + reversal + shift) to prevent casual reading |
| 🔁 **可重用 OTP** | 密钥长度 ≥ 明文长度,消除周期规律,实现 OTP 级别的安全性 | | 🔁 **Reusable OTP** | Key length ≥ plaintext length, eliminating periodic patterns—OTP-level security |
| 🛡️ **抗量子攻击** | 无数学结构,Shor/Grover 均无法加速暴力破解 | | 🛡️ **Quantum-resistant** | No math structure, so Shor/Grover can't speed up brute force |
| 🚫 **无第三方依赖** | 不依赖 OpenSSL、Crypto 等任何加密库 | | 🚫 **Zero third-party deps** | No OpenSSL, no Crypto, no nothing |
| 📦 **即开即用** | 交互式菜单,支持多密钥文件切换 | | 📦 **Ready to use** | Interactive menu, multiple key file support |
| 🐍 **纯 Python** | 仅需 Python 3.6+,零额外依赖 | | 🐍 **Pure Python** | Just Python 3.6+, no extra dependencies |
| 💬 **加密聊天(v2.0)** | ChaosCryptChat 端到端加密聊天:文本/图片/文件/语音,P2P + 中央服务器双模式 | | 💬 **Encrypted Chat (v2.0)** | ChaosCryptChat: E2E text/images/files/voice, P2P + central server modes |
--- ---
## 加密流程详解 ## Encryption Workflow
``` ```
明文 Plaintext
↓ ↓
① Base64 编码 ① Base64 encode
↓ ↓
② 随机替换表(大小写各26字母完全打乱) ② Random substitution (26 uppercase + 26 lowercase fully shuffled)
↓ ↓
③ 大小写翻转(10位随机模式) ③ Case flip (10‑bit random pattern)
↓ ↓
④ 字符串反转 ④ String reversal
↓ ↓
⑤ 动态异或(4096位长密钥) ⑤ Dynamic XOR (4096‑bit long key)
↓ ↓
⑥ 最终异或(用户密码 + 512位短密钥 派生) ⑥ Final XOR (user password + 512‑bit short key derived)
↓ ↓
密文(十六进制) Ciphertext (hex)
``` ```
每一步使用的随机参数都来自 `.key` 文件,用户密码仅参与最后一步的密钥派生。 Every random parameter comes from the `.key` file. The user password is only used in the final key derivation step.
### 密钥派生流程 ### Key Derivation Flow
``` ```
用户密码 + short_key (512位) User password + short_key (512 bits)
↓ ↓
交替穿插 → 位运算混合 → 分组置换 → 反转 Interleave → bitwise mixing → block permutation → reversal
↓ ↓
扩展至目标长度(三种变换模式循环) Expand to target length (three transformation modes cycled)
↓ ↓
最终密钥(长度 >= 明文) Final key (length ≥ plaintext)
``` ```
--- ---
## 安全性分析 ## Security Analysis
### 1. 无法建立数学方程 ### 1. No Mathematical Equations to Write
| 传统算法 | 方程形式 | 攻击方式 | | Traditional Alg | Equation Form | Attack Vector |
|----------|----------|----------| |-----------------|---------------|---------------|
| RSA | c = m^e mod n | 数域筛法、Shor | | RSA | c = m^e mod n | Number field sieve, Shor |
| AES | State = SBox ∘ ShiftRow ∘ MixCol ∘ AddRoundKey | 差分分析、Grover | | AES | State = SBox ∘ ShiftRow ∘ MixCol ∘ AddRoundKey | Differential, Grover |
| ECC | Q = kP | 离散对数、Shor | | ECC | Q = kP | Discrete log, Shor |
| **ChaosCrypt** | **无法写出任何有意义的方程** | **只能暴力枚举** | | **ChaosCrypt** | **No meaningful equation can be written** | **Brute force only** |
> 原因:替换表是查表操作,翻转模式是硬编码数组,密钥派生是黑盒混合——每一步都是"随机查表",没有可解析的代数结构。 > Why: substitution is table lookup, flip pattern is a hardcoded array, key derivation is a black-box mix—every step is "random table lookup" with no parseable algebraic structure.
### 2. 密钥空间(暴力破解难度) ### 2. Key Space (Brute‑Force Difficulty)
| 组件 | 空间大小 | 数值 | | Component | Space Size | Approx. Value |
|------|----------|------| |-----------|------------|---------------|
| `upper_mapping` | 26! | ~10²⁶ | | `upper_mapping` | 26! | ~10²⁶ |
| `lower_mapping` | 26! | ~10²⁶ | | `lower_mapping` | 26! | ~10²⁶ |
| `digit_mapping` | ~10! × C(62,10) | ~10¹⁴ | | `digit_mapping` | ~10! × C(62,10) | ~10¹⁴ |
| `equal_mapping` | 62×61×60×59 | ~10⁷ | | `equal_mapping` | 62×61×60×59 | ~10⁷ |
| `long_key` (4096位hex) | 16⁴⁰⁹⁶ | ~10⁴⁹³² | | `long_key` (4096‑bit hex) | 16⁴⁰⁹⁶ | ~10⁴⁹³² |
| `short_key` (512位hex) | 16⁵¹² | ~10⁶¹⁶ | | `short_key` (512‑bit hex) | 16⁵¹² | ~10⁶¹⁶ |
| `flip_pattern` | 2¹⁰ | ~10³ | | `flip_pattern` | 2¹⁰ | ~10³ |
| 用户密码(最低8位) | ~10⁸ | | | User password (min 8 chars) | ~10⁸ | |
**总搜索空间 ≈ 10⁵⁶³²** **Total search space ≈ 10⁵⁶³²**
**对比数据**: **Comparisons**:
- 宇宙原子总数:≈ 10⁸⁰ - Atoms in the observable universe: ≈ 10⁸⁰
- AES-256 密钥空间:≈ 10⁷⁷ - AES‑256 key space: ≈ 10⁷⁷
- RSA-2048 密钥空间:≈ 10⁶¹⁶ - RSA‑2048 key space: ≈ 10⁶¹⁶
- **ChaosCrypt:≈ 10⁵⁶³²**(是 AES 的 10⁵⁵⁵⁵ 倍) - **ChaosCrypt: ≈ 10⁵⁶³²** (10⁵⁵⁵⁵ × AES)
> **即使全宇宙原子都变成量子计算机,也无法在宇宙生命周期内枚举完。** > **Even if every atom in the universe were a quantum computer, they couldn't exhaust this space before the heat death of the cosmos.**
### 3. 量子安全性 ### 3. Quantum Resistance
| 量子算法 | 目标 | 对 ChaosCrypt 的效果 | | Quantum Alg | Target | Effect on ChaosCrypt |
|----------|------|------------------------| |-------------|--------|----------------------|
| **Shor** | 分解质数、离散对数 | ❌ **无效** – 没有数论结构 | | **Shor** | Integer factorization, discrete log | ❌ **Ineffective** – no number‑theoretic structure |
| **Grover** | 对称加密加速 | ❌ **无效** – 空间 10⁵⁶³²,开根号后 10²⁸¹⁶,依然远大于 10⁸⁰ | | **Grover** | Symmetric encryption speedup | ❌ **Ineffective** – space 10⁵⁶³², sqrt gives 10²⁸¹⁶, still >> 10⁸⁰ |
**结论:ChaosCrypt 对抗已知量子攻击完全免疫。** **Conclusion: ChaosCrypt is fully immune to known quantum attacks.**
### 4. 经典攻击方式评估 ### 4. Classical Attack Vectors
| 攻击方式 | 是否可行 | 原因 | | Attack | Feasible? | Reason |
|----------|----------|------| |--------|-----------|--------|
| 频率分析 | ❌ | 随机替换表破坏频率分布 | | Frequency analysis | ❌ | Random substitution destroys frequency patterns |
| 周期分析 | ❌ | 密钥长度 ≥ 明文,无循环 | | Periodicity analysis | ❌ | Key length ≥ plaintext, no cycles |
| 已知明文攻击 | ❌ | 非线性操作 → 超定方程组无解 | | Known‑plaintext attack | ❌ | Nonlinear ops → overdetermined system with no solution |
| 选择明文攻击 | ❌ | 即使可控输入也无法反推黑盒映射 | | Chosen‑plaintext attack | ❌ | Even controllable input can't invert the black‑box mapping |
| 差分/线性攻击 | ❌ | 无代数结构,无法建立差分链 | | Differential/linear | ❌ | No algebraic structure to build differential chains |
| 暴力枚举 | ❌ | 空间 10⁵⁶³²,物理上不可能 | | Brute force | ❌ | Space 10⁵⁶³², physically impossible |
**唯一现实威胁**:盗取 `.key` 文件 + 窃取用户密码(端侧攻击,与算法无关)。 **The only real threat**: Theft of `.key` file + password (client‑side compromise, unrelated to the algorithm).
--- ---
## 为什么这玩意儿真的安全?(不服来辩版) ## Why This Is Actually Secure (No‑BS Edition)
**总之就是安全——真·安全。** 🤷‍♂️ **Bottom line: It's secure — genuinely secure.** 🤷‍♂️
我寻思着,总不能所有加密算法都得围着椭圆曲线和质数分解转,然后等 NIST 给你盖个戳才算"安全"吧?那算什么东西?**垄断啊?** 🤣 Look, not every encryption algorithm has to revolve around elliptic curves and prime factorization, waiting for NIST to stamp it "secure." That's not security—that's **a monopoly.** 🤣
再说了,美国政府什么心思你猜不透。**Dual_EC_DRBG 的事儿这么快就忘了?** NIST 认证的、标准化的、全世界用了好几年的算法——结果里面养着 NSA 的后门。标准管个屁用。 And let's not forget **Dual_EC_DRBG** — NIST‑certified, standardized, used worldwide for years… and it had an NSA backdoor baked in. So much for standards.
所以别跟我扯什么"学术界验证"、"第三方审计"、"算法标准认证"。我就问一句: So don't give me "academic verification," "third‑party audit," or "standard certification." I'll ask you one question:
**只有这些"标准"算法才能叫安全?** **Are only those "standard" algorithms allowed to be secure?**
- **安全 ≠ 数学复杂** - **Secure ≠ mathematically complex**
- **安全 ≠ NIST 认证** - **Secure ≠ NIST‑approved**
--- ---
来,咱们看看所谓的"标准算法"都什么下场: Let's see how those "standard" algorithms fare:
| 算法 | 密钥空间 | 量子下场 | | Algorithm | Key Space | Quantum Fate |
|------|----------|----------| |-----------|-----------|--------------|
| AES-256 | 10⁷⁷ | Grover 减半到 10³⁸ → 理论上可破 | | AES‑256 | 10⁷⁷ | Grover halves it to 10³⁸ → theoretically breakable |
| RSA-2048 | 10⁶¹⁶ | Shor 一来直接秒死 🔥 | | RSA‑2048 | 10⁶¹⁶ | Shor kills it instantly 🔥 |
| ECC | 10⁶¹⁶ | 同上,Shor 直接扼杀 | | ECC | 10⁶¹⁶ | Same, Shor shuts it down |
再看看我这个: Now look at this:
| 算法 | 密钥空间 | 量子下场 | | Algorithm | Key Space | Quantum Fate |
|------|----------|----------| |-----------|-----------|--------------|
| **ChaosCrypt** | **10⁵⁶³²** | **Shor 无从下手,Grover 打了等于没打** ✅ | | **ChaosCrypt** | **10⁵⁶³²** | **Shor has nothing to attack, Grover barely scratches it** ✅ |
**10⁵⁶³² 什么概念?** **10⁵⁶³² — what does that mean?**
全宇宙原子总数才 10⁸⁰。就算把全宇宙每个原子都变成一台量子计算机,从宇宙大爆炸算到今天,**也算不完这个空间的一个零头。** The universe has ~10⁸⁰ atoms. Even if every atom were a quantum computer running from the Big Bang to now, they wouldn't finish a fraction of this space.
AES 的 10⁷⁷ 在它面前就像一粒沙子对比整个银河系。 AES's 10⁷⁷ is a grain of sand compared to the Milky Way.
--- ---
**RSA 美丽吧?标准吧?数学优美吧?** **RSA is beautiful, right? Standard? Mathematically elegant?**
但恰恰因为**太数学了**,所以 Shor 一发入魂,直接物理超度。 But precisely because it's **too mathematical**, Shor one‑shots it.
**数学上越好看,结构越清晰,攻击者就越开心**——因为你有方程,他就能解;你有规律,他就能抓;你有结构,他就能拆。 **The prettier the math, the clearer the structure, the happier the attacker** — because you have equations they can solve, patterns they can exploit, structure they can dismantle.
我的算法呢? My algorithm?
- 替换表?随机打的,没有规律。 - Substitution? Randomly shuffled — no pattern.
- 翻转模式?硬编码数组,没有方程。 - Flip pattern? Hardcoded array — no equation.
- 密钥派生?黑盒操作,解不出来。 - Key derivation? Black‑box mix — unsolvable.
**攻击者想写个方程都写不出来,想用代数工具都找不到切入点。** **An attacker can't even write an equation. There's no algebraic handle to grab.**
--- ---
**所以这算法有什么问题?** **So what's wrong with this algorithm?**
- ❌ 没有"第三方安全审计" - ❌ No "third‑party security audit"
- ❌ 没有"算法标准认证" - ❌ No "algorithm standard certification"
- ❌ 没有"学术界验证" - ❌ No "academic validation"
- ❌ 并且"看起来肥肠初级" - ❌ And it "looks pretty amateur"
**除此之外,没有任何问题。** 🤷‍♂️ **Other than that, absolutely nothing.** 🤷‍♂️
看起来初级就初级,**你能攻破么?不能!** Looks amateur? Fine. **Can you break it? No.**
安全这两个字,只关心**实战**,不关心**评价**和**认证**。 Security is about **real‑world results**, not **reviews** or **certifications**.
- Dual_EC_DRBG 有认证有标准有审计——结果呢?后门。 - Dual_EC_DRBG had certs, standards, audits — and a backdoor.
- 我这个啥都没有——结果呢?**你破不了。** - This has none of that — and **you can't break it.**
**能被黑客破解的就是垃圾,破解不了的就是真神。** **If hackers can crack it, it's garbage. If they can't, it's the real deal.**
这玩意儿你实说,**你找不出来毛病!** 😏🔥 Seriously — **find a flaw. I dare you.** 😏🔥
--- ---
## 💬 ChaosCryptChat 混沌加密聊天(v2.0 新增) ## 💬 ChaosCryptChat (v2.0 New)
**ChaosCryptChat** 是基于 ChaosCrypt 混沌加密内核构建的端到端加密聊天系统。所有聊天内容(文本、图片、文件、语音)在发送前均经混沌加密,服务器与中间节点无法读取任何消息。 **ChaosCryptChat** is an end‑to‑end encrypted chat system built on the ChaosCrypt kernel. All content (text, images, files, voice) is chaos‑encrypted before sending—servers and middlemen cannot read any messages.
### 核心特性 ### Core Features
| 特性 | 说明 | | Feature | Description |
|------|------| |---------|-------------|
| 🔗 **端到端加密** | 所有消息客户端本地加密,服务器只做中继,不持有群密钥 | | 🔗 **End‑to‑end encryption** | All messages encrypted client‑side; server only relays, holds no group keys |
| ☁️ **双群模式** | 🔗 端到端 P2P 直连 + ☁️ 中央服务器(解决 NAT 穿透) | | ☁️ **Two group modes** | 🔗 P2P direct + ☁️ Central server (NAT traversal) |
| 🎤 **语音消息** | 录音 → 混沌加密 → 发送 → 解密播放 | | 🎤 **Voice messages** | Record → chaos encrypt → send → decrypt & play |
| 🖼️ **图片/文件** | 二进制数据混沌加密传输,支持任意文件类型 | | 🖼️ **Images / Files** | Binary data encrypted with ChaosCrypt, supports any file type |
| 👥 **群管理** | 创建群、加入群、群名、公告、踢人、群主审批 | | 👥 **Group management** | Create, join, group name, announcements, kick, owner approval |
| 🚫 **消息撤回** | 2 分钟内可撤回自己的消息 | | 🚫 **Message recall** | Recall within 2 minutes of sending |
| 🔑 **每用户密钥** | 每用户独立密钥认证,防止冒充他人 | | 🔑 **Per‑user keys** | Each user has an independent authentication key to prevent impersonation |
| 📜 **历史记录** | SQLite 本地存储聊天历史(重启不丢) | | 📜 **History** | SQLite local storage (persists across restarts) |
| 🛡️ **HMAC 校验** | 每条消息带 HMAC 签名,防篡改、防伪造 | | 🛡️ **HMAC verification** | Every message carries an HMAC signature to prevent tampering and forgery |
| 📱 **密钥分享** | 群密钥支持复制 / 二维码 / 文件三种方式分享 | | 📱 **Key sharing** | Group key can be shared via copy / QR code / file |
### 两种群模式 ### Two Group Modes
**① 端到端(P2P)群聊**:群主即服务器,成员直连群主主机,适合局域网或公网 IP 场景。群密钥由群主生成并分享给成员。 **① End‑to‑End (P2P) Group**: The group owner acts as the server; members connect directly to the owner's host. Ideal for LAN or public‑IP environments. The owner generates the group key and shares it with members.
**② 中央服务器群聊**:运行 `server.py`(公网 IP)解决 NAT 穿透。服务器只负责用户认证、群成员管理、消息中继——**不持有群密钥,无法解密任何消息**。 **② Central Server Group**: Run `server.py` (public IP) to handle NAT traversal. The server only handles user authentication, group membership, and message relaying—**it does not hold group keys and cannot decrypt any messages.**
### 快速启动 ### Quick Start
#### 启动聊天客户端 #### Launch the Chat Client
```bash ```bash
cd ChaosCryptChat cd ChaosCryptChat
python qtmain.py python qtmain.py
``` ```
#### 启动中央服务器(可选,公网/NAT 场景) #### Launch the Central Server (optional, for public/NAT scenarios)
```bash ```bash
cd ChaosCryptChat cd ChaosCryptChat
python server.py 8666 python server.py 8666
``` ```
#### 安装依赖 #### Install Dependencies
```bash ```bash
pip install PyQt5 # 必需,GUI 界面 pip install PyQt5 # Required, GUI
pip install pygame # 语音播放(可选) pip install pygame # Audio playback (optional)
pip install sounddevice numpy # 录音(可选,或 pyaudio) pip install sounddevice numpy # Recording (optional, or pyaudio)
pip install Pillow # 图片显示(可选) pip install Pillow # Image display (optional)
pip install qrcode # 群密钥二维码(可选) pip install qrcode # Group key QR codes (optional)
``` ```
> 除 PyQt5 外均为可选依赖,未安装时对应功能自动禁用。 > Only PyQt5 is required; all others are optional. Missing dependencies disable their respective features gracefully.
### 使用流程 ### Usage Workflow
1. **注册/登录**:启动后创建本地账户(PBKDF2 密码哈希,支持自动登录) 1. **Register / Login**: Create a local account on startup (PBKDF2 password hash, auto‑login supported)
2. **创建群**:点击「📡 创建群」,将群密钥复制/生成二维码分享给好友 2. **Create a Group**: Click 「📡 Create Group」, copy the group key or generate a QR code to share with friends
3. **加入群**:点击「📥 加入群」,粘贴群密钥或扫码加入 3. **Join a Group**: Click 「📥 Join Group」, paste the group key or scan the QR code
4. **开始聊天**:发送文本/图片/文件/语音;右键消息可撤回、分享、下载;群主可踢人、设公告、改群名 4. **Start Chatting**: Send text, images, files, voice messages; right‑click to recall, share, or download; group owners can kick, set announcements, and change group names
--- ---
## 快速开始 ## Quick Start
### 安装 ### Installation
```bash ```bash
# 克隆仓库 # Clone the repository
git clone https://gitcode.com/dvsxt/chaoscrypt.git git clone https://gitcode.com/dvsxt/chaoscrypt.git
git clone https://github.com/dvs-dvsxt/ChaosCrypt.git git clone https://github.com/dvs-dvsxt/ChaosCrypt.git
cd chaoscrypt cd chaoscrypt
# 核心模块零依赖,Python 3.6+ 即可;ChaosCryptChat 需 PyQt5 # Core module has zero dependencies — Python 3.6+ only
# ChaosCryptChat requires PyQt5
``` ```
### 五分钟上手 ### Five‑Minute Example
```python ```python
from chaoscrypt import EncryptionSystem from chaoscrypt import EncryptionSystem
# 初始化(自动加载默认密钥,不存在则生成) # Initialize (auto‑loads default key; generates one if missing)
crypto = EncryptionSystem() crypto = EncryptionSystem()
# 加密 # Encrypt
cipher = crypto.encrypt("Hello World", user_password="MyP@ssw0rd2024!") cipher = crypto.encrypt("Hello World", user_password="MyP@ssw0rd2024!")
print(cipher) print(cipher)
# 解密 # Decrypt
plain = crypto.decrypt(cipher, user_password="MyP@ssw0rd2024!") plain = crypto.decrypt(cipher, user_password="MyP@ssw0rd2024!")
print(plain) # Hello World print(plain) # Hello World
``` ```
### 命令行交互 ### Command‑Line Interactive Mode
```bash ```bash
python chaoscrypt.py python chaoscrypt.py
@@ -347,51 +349,51 @@ python chaoscrypt.py
--- ---
## 使用指南 ## Usage Guide
### 交互菜单 ### Interactive Menu
``` ```
请选择操作: Please select an action:
1. 使用默认密钥加密 1. Encrypt using the default key
2. 使用默认密钥解密 2. Decrypt using the default key
3. 生成新密钥(覆盖默认) 3. Generate a new key (overwrite default)
4. 使用指定密钥文件加密 4. Encrypt using a specified key file
5. 使用指定密钥文件解密 5. Decrypt using a specified key file
6. 生成密钥并保存到当前文件夹 6. Generate a key and save to current folder
7. 查看当前密钥信息 7. View current key info
8. 退出 8. Exit
``` ```
### 密钥文件 ### Key File
密钥文件以混淆形式存储,防止普通用户直接阅读。内容包括: Keys are stored in an obfuscated format to prevent casual reading. Contents include:
- `upper_mapping` – 大写字母随机替换表 - `upper_mapping` – random substitution for uppercase letters
- `lower_mapping` – 小写字母随机替换表 - `lower_mapping` – random substitution for lowercase letters
- `digit_mapping` – 数字→字符映射 - `digit_mapping` – digit‑to‑character mapping
- `equal_mapping` – 等号映射 - `equal_mapping` – equal‑sign mapping
- `long_key` – 4096位十六进制密钥 - `long_key` – 4096‑bit hexadecimal key
- `short_key` – 512位十六进制密钥 - `short_key` – 512‑bit hexadecimal key
- `generated_at` – 生成时间戳 - `generated_at` – timestamp
--- ---
## API 参考 ## API Reference
### `EncryptionSystem(key_file=None)` ### `EncryptionSystem(key_file=None)`
初始化加密系统。 Initialize the encryption system.
**参数:** **Parameters:**
- `key_file` (str, optional) – 密钥文件路径。若为 None,自动加载 `encryption.key`;若不存在则生成。 - `key_file` (str, optional) – path to the key file. If `None`, loads `encryption.key`; generates one if missing.
**示例:** **Example:**
```python ```python
# 使用默认密钥 # Use default key
crypto = EncryptionSystem() crypto = EncryptionSystem()
# 使用指定密钥 # Use a custom key file
crypto = EncryptionSystem("my_key.key") crypto = EncryptionSystem("my_key.key")
``` ```
@@ -399,16 +401,16 @@ crypto = EncryptionSystem("my_key.key")
### `encrypt(plaintext, user_password)` ### `encrypt(plaintext, user_password)`
加密明文。 Encrypt plaintext.
**参数:** **Parameters:**
- `plaintext` (str) – 待加密文本 - `plaintext` (str) – text to encrypt
- `user_password` (str) – 用户密码 - `user_password` (str) – user password
**返回:** **Returns:**
- `str` – 十六进制密文 - `str` – hexadecimal ciphertext
**示例:** **Example:**
```python ```python
cipher = crypto.encrypt("Hello", "myPass123") cipher = crypto.encrypt("Hello", "myPass123")
``` ```
@@ -417,16 +419,16 @@ cipher = crypto.encrypt("Hello", "myPass123")
### `decrypt(ciphertext, user_password)` ### `decrypt(ciphertext, user_password)`
解密密文。 Decrypt ciphertext.
**参数:** **Parameters:**
- `ciphertext` (str) – 十六进制密文 - `ciphertext` (str) – hexadecimal ciphertext
- `user_password` (str) – 用户密码 - `user_password` (str) – user password
**返回:** **Returns:**
- `str` – 解密后的明文,失败时返回错误信息 - `str` – decrypted plaintext, or an error message on failure
**示例:** **Example:**
```python ```python
plain = crypto.decrypt("a1b2c3...", "myPass123") plain = crypto.decrypt("a1b2c3...", "myPass123")
``` ```
@@ -435,99 +437,99 @@ plain = crypto.decrypt("a1b2c3...", "myPass123")
### `generate_keys(save_path=None)` ### `generate_keys(save_path=None)`
生成新的随机密钥并保存。 Generate new random keys and save them.
**参数:** **Parameters:**
- `save_path` (str, optional) – 保存路径,默认 `key_{timestamp}.key` - `save_path` (str, optional) – save path; defaults to `key_{timestamp}.key`
**返回:** **Returns:**
- `str` – 保存的文件路径 - `str` – the saved file path
--- ---
### `print_keys()` ### `print_keys()`
打印当前密钥信息。 Print the current key information.
--- ---
## 常见问题 ## FAQ
**Q:这算法经过审计吗?** **Q: Has this algorithm been audited?**
A:没有。但我们认为**没有审计 ≠ 不安全**,Dual_EC_DRBG 经过审计却是后门。审计只是参考,不是真理。 A: No. But we believe **no audit ≠ insecure** — Dual_EC_DRBG was audited and backdoored. Audits are references, not truth.
**Q:为什么不直接用 AES?** **Q: Why not just use AES?**
A:AES 很好,但它是"标准"算法,有代数结构,Grover 可以加速。我们选择另一条路——**完全随机、无结构、超大空间**。 A: AES is great, but it's a "standard" algorithm with algebraic structure, and Grover can speed it up. We chose a different path — **fully random, structure‑free, and enormous.**
**Q:如果黑客拿到了 `.key` 文件和密文,但不知道密码呢?** **Q: What if an attacker gets the `.key` file and the ciphertext, but not the password?**
A:那他就只能暴力破解密码。如果密码是 12 位以上强密码,破解时间以年为单位。 A: Then they're left with brute‑forcing the password. If the password is 12+ characters strong, that's years of work.
**Q:如果黑客同时拿到了 `.key`、密文、密码呢?** **Q: What if the attacker gets the `.key`, ciphertext, and password?**
A:那你的系统已经不属于"加密被攻破",而是"钥匙被偷"——这是端侧安全问题,任何加密算法都防不住。 A: Then your system isn't "crypto broken" — it's "keys stolen." That's a client‑side security issue, which no encryption algorithm can prevent.
**Q:这算法有数学证明吗?** **Q: Is there a mathematical proof for this?**
A:有。证明如下: A: Yes. The proof is:
- 无法建立数学模型 → 无代数攻击路径 - No mathematical model can be constructed → no algebraic attacks
- 密钥空间 10⁵⁶³² → 暴力不可能 - Key space 10⁵⁶³² → brute force impossible
- 量子加速无效 → 抗量子 - Quantum speedups don't help → quantum‑resistant
这个证明比任何"归约到难问题"都更硬——因为**没有结构可归约,只能枚举**。 This proof is stronger than any "reduction to a hard problem" — because **there's no structure to reduce, only exhaustive search.**
**Q:看起来好初级,真能用?** **Q: It looks so amateurish — is it actually usable?**
A:初级和安全没有半毛钱关系。你长得好看能挡子弹吗?能破就是能破,不能破就是不能破。**你破一个试试?** A: Looking amateur and being secure have nothing to do with each other. Can you break it or not? **Try it.**
**Q:ChaosCryptChat 聊天安全吗?** **Q: Is ChaosCryptChat secure?**
A:端到端加密——消息在客户端用群密钥混沌加密,服务器只转发密文、不持有密钥。即使服务器被入侵也拿不到聊天内容。 A: End‑to‑end — messages are encrypted client‑side with the group key; the server forwards only ciphertext and holds no keys. Even if the server is breached, chat contents remain private.
**Q:聊天密钥怎么分享?** **Q: How do I share the group key?**
A:群主创建群后生成群密钥,可通过复制文本、二维码、密钥文件三种方式分享。请走可信渠道传递,避免被中间人截获。 A: After creating a group, the owner can share the key via copied text, QR code, or key file. Use a trusted channel to avoid MITM interception.
**Q:ChaosCryptChat 需要公网 IP 吗?** **Q: Does ChaosCryptChat require a public IP?**
A:不需要。局域网用 P2P 直连即可;跨网络用中央服务器(server.py)中继,解决 NAT 穿透。 A: No. Use P2P for LAN; for cross‑network, the central server (`server.py`) relays traffic to handle NAT.
--- ---
## 项目结构 ## Project Structure
``` ```
chaoscrypt/ chaoscrypt/
├── chaoscrypt.py # 主程序(加密/解密/密钥管理) ├── chaoscrypt.py # Main program (encrypt/decrypt/key management)
├── README.md # 本文档 ├── README.md # This document
├── SECURITY.md # 安全说明文档 ├── SECURITY.md # Security details
└── ChaosCryptChat/ # 💬 混沌加密聊天(v2.0 新增) └── ChaosCryptChat/ # 💬 Encrypted Chat (v2.0 new)
├── qtmain.py # PyQt5 聊天客户端(端到端加密) ├── qtmain.py # PyQt5 chat client (E2E encrypted)
└── server.py # ☁️ 中央服务器(NAT 穿透 / 消息中继) └── server.py # ☁️ Central server (NAT traversal / message relay)
``` ```
核心就三个文件,零依赖;ChaosCryptChat 是 v2.0 新增的加密聊天模块。 The core is just three files with zero dependencies; ChaosCryptChat is the v2.0 addition.
--- ---
## 免责声明 ## Disclaimer
> **本系统仅供学习研究使用。** > **This system is for educational and research purposes only.**
> 作者不承担因密钥文件泄露、密码失窃、端侧入侵等导致的任何数据损失责任。 > The author assumes no liability for data loss due to key file leakage, password theft, or client‑side compromise.
> 生产环境请确保 `.key` 文件和用户密码均安全存储,并考虑强制用户使用强密码策略。 > In production, ensure the `.key` file and user password are stored securely, and enforce strong password policies.
> **ChaosCryptChat** 服务器不持有群密钥,但会记录用户登录信息与消息中继日志,请谨慎选择信任的服务器。 > **ChaosCryptChat** servers do not hold group keys, but they do log login information and relay metadata—choose your server wisely.
> 聊天密钥由群主分享,请通过可信渠道传递;即使服务器被攻陷也不会泄露历史聊天内容。 > Group keys are shared by the group owner; transmit them over trusted channels. Even if the server is compromised, historical chat content remains private.
--- ---
## 📜 许可证 ## 📜 License
MIT License — 你可以自由使用、修改、分发,但请保留原作者声明。 MIT License — you are free to use, modify, and distribute, but please retain the original attribution.
--- ---
## 🙏 致谢 ## 🙏 Acknowledgments
感谢所有认真看完这份文档的人。 Thank you to everyone who read this document carefully.
你是极少数愿意**用逻辑判断安全,而不是用头衔判断安全**的人。 You are among the few who judge security by **logic**, not by **credentials**.
--- ---
**"安全应该由攻击难度定义,而不是由某个机构盖章定义。"** **"Security should be defined by the difficulty of attack, not by a stamp from an institution."**
—— ChaosCrypt 设计哲学 — ChaosCrypt Design Philosophy
--- ---
+272 -160
View File
@@ -1,3 +1,7 @@
"""
A multi-layer encryption system with key management, substitution ciphers,
XOR operations, and dynamic key derivation.
"""
import base64 import base64
import json import json
@@ -5,12 +9,23 @@ import os
import time import time
from datetime import datetime from datetime import datetime
class EncryptionSystem: class EncryptionSystem:
"""Main encryption engine with key-based transformation layers."""
def __init__(self, key_file=None, key_password=None): def __init__(self, key_file=None, key_password=None):
"""
Initialize the encryption system with an optional key file.
Args:
key_file: Path to the encryption key file.
key_password: Password for decrypting the key file.
"""
self.key_file = key_file self.key_file = key_file
self.key_password = key_password self.key_password = key_password
self.keys_loaded = False self.keys_loaded = False
# Base64 special character mappings for safe transport
self.special_encrypt = { self.special_encrypt = {
'+': '.', '+': '.',
'/': "'", '/': "'",
@@ -23,38 +38,46 @@ class EncryptionSystem:
self.flip_pattern = None self.flip_pattern = None
# Try loading the key file if provided or find default
if key_file: if key_file:
if os.path.exists(key_file): if os.path.exists(key_file):
if key_password is None: if key_password is None:
key_password = input(f"请输入密钥文件 {key_file} 的密码: ") key_password = input(f"Enter password for key file {key_file}: ")
self._load_keys(key_file, key_password) self._load_keys(key_file, key_password)
self.keys_loaded = True self.keys_loaded = True
else: else:
print(f"⚠️ 密钥文件 {key_file} 不存在") print(f"⚠️ Key file {key_file} not found")
self.keys_loaded = False self.keys_loaded = False
else: else:
default_key = "encryption.key" default_key = "encryption.key"
if os.path.exists(default_key): if os.path.exists(default_key):
self.key_file = default_key self.key_file = default_key
if key_password is None: if key_password is None:
key_password = input(f"请输入密钥文件 {default_key} 的密码: ") key_password = input(f"Enter password for key file {default_key}: ")
self._load_keys(default_key, key_password) self._load_keys(default_key, key_password)
self.keys_loaded = True self.keys_loaded = True
else: else:
print("=" * 60) print("=" * 60)
print("首次启动,请先生成密钥文件") print("First launch detected. Please generate a key file first.")
print("=" * 60) print("=" * 60)
self.keys_loaded = False self.keys_loaded = False
# ----------------------------------------------------------------------
# Key generation utilities
# ----------------------------------------------------------------------
def _generate_random_alphabet(self, lowercase=False): def _generate_random_alphabet(self, lowercase=False):
"""Generate a shuffled alphabet string."""
chars = list("abcdefghijklmnopqrstuvwxyz" if lowercase else "ABCDEFGHIJKLMNOPQRSTUVWXYZ") chars = list("abcdefghijklmnopqrstuvwxyz" if lowercase else "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
n = len(chars) n = len(chars)
# Fisher-Yates shuffle using secure random bytes
for i in range(n - 1, 0, -1): for i in range(n - 1, 0, -1):
j = int.from_bytes(os.urandom(1), 'big') % (i + 1) j = int.from_bytes(os.urandom(1), 'big') % (i + 1)
chars[i], chars[j] = chars[j], chars[i] chars[i], chars[j] = chars[j], chars[i]
return ''.join(chars) return ''.join(chars)
def _generate_random_digit_mapping(self): def _generate_random_digit_mapping(self):
"""Create a random mapping for digits 0-9 to alphabet characters."""
digits = list("0123456789") digits = list("0123456789")
mapping_chars = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") mapping_chars = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
n = len(mapping_chars) n = len(mapping_chars)
@@ -67,72 +90,69 @@ class EncryptionSystem:
return mapping return mapping
def _generate_random_equal_mapping(self): def _generate_random_equal_mapping(self):
"""Generate mapping for Base64 padding count (0-3)."""
chars = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") chars = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
n = len(chars) n = len(chars)
for i in range(n - 1, 0, -1): for i in range(n - 1, 0, -1):
j = int.from_bytes(os.urandom(1), 'big') % (i + 1) j = int.from_bytes(os.urandom(1), 'big') % (i + 1)
chars[i], chars[j] = chars[j], chars[i] chars[i], chars[j] = chars[j], chars[i]
mapping = { return {
'0': chars[0], '0': chars[0],
'1': chars[1], '1': chars[1],
'2': chars[2], '2': chars[2],
'3': chars[3] '3': chars[3]
} }
return mapping
def _generate_random_flip_pattern(self): def _generate_random_flip_pattern(self):
pattern = [] """Generate a 10-bit pattern for case-flipping."""
for _ in range(10): return [int.from_bytes(os.urandom(1), 'big') % 2 for _ in range(10)]
bit = int.from_bytes(os.urandom(1), 'big') % 2
pattern.append(bit)
return pattern
def _generate_long_key(self, length=4096): def _generate_long_key(self, length=4096):
"""Generate a long hex key (4096 chars by default)."""
chars = "0123456789abcdef" chars = "0123456789abcdef"
result = [] return ''.join(chars[int.from_bytes(os.urandom(1), 'big') % 16] for _ in range(length))
for _ in range(length):
idx = int.from_bytes(os.urandom(1), 'big') % 16
result.append(chars[idx])
return ''.join(result)
def _generate_short_key(self, length=512): def _generate_short_key(self, length=512):
"""Generate a short hex key (512 chars by default)."""
chars = "0123456789abcdef" chars = "0123456789abcdef"
result = [] return ''.join(chars[int.from_bytes(os.urandom(1), 'big') % 16] for _ in range(length))
for _ in range(length):
idx = int.from_bytes(os.urandom(1), 'big') % 16 # ----------------------------------------------------------------------
result.append(chars[idx]) # Key obfuscation and persistence
return ''.join(result) # ----------------------------------------------------------------------
def _obfuscate_keys(self, keys_data): def _obfuscate_keys(self, keys_data):
"""Obfuscate key data using base64 + reversal + Caesar shift."""
json_str = json.dumps(keys_data) json_str = json.dumps(keys_data)
b64 = base64.b64encode(json_str.encode()).decode() b64 = base64.b64encode(json_str.encode()).decode()
reversed_b64 = b64[::-1] reversed_b64 = b64[::-1]
shifted = ''.join([chr((ord(c) + 1) % 128) for c in reversed_b64]) shifted = ''.join(chr((ord(c) + 1) % 128) for c in reversed_b64)
final = base64.b64encode(shifted.encode()).decode() return base64.b64encode(shifted.encode()).decode()
return final
def _deobfuscate_keys(self, obfuscated_data): def _deobfuscate_keys(self, obfuscated_data):
"""Reverse the obfuscation to recover original key data."""
try: try:
shifted = base64.b64decode(obfuscated_data.encode()).decode() shifted = base64.b64decode(obfuscated_data.encode()).decode()
reversed_b64 = ''.join([chr((ord(c) - 1) % 128) for c in shifted]) reversed_b64 = ''.join(chr((ord(c) - 1) % 128) for c in shifted)
b64 = reversed_b64[::-1] b64 = reversed_b64[::-1]
json_str = base64.b64decode(b64.encode()).decode() json_str = base64.b64decode(b64.encode()).decode()
return json.loads(json_str) return json.loads(json_str)
except Exception: except Exception as exc:
raise Exception("密钥文件损坏") raise Exception("Key file corrupted") from exc
def _xor_encrypt_data(self, data, password): def _xor_encrypt_data(self, data, password):
result = [] """XOR encrypt data with a password, returning hex string."""
key_len = len(password) key_len = len(password)
for i, char in enumerate(data): return ''.join(
xor_result = ord(char) ^ ord(password[i % key_len]) f"{ord(char) ^ ord(password[i % key_len]):02x}"
result.append(f"{xor_result:02x}") for i, char in enumerate(data)
return ''.join(result) )
def _xor_decrypt_data(self, hex_data, password): def _xor_decrypt_data(self, hex_data, password):
"""XOR decrypt hex data with a password."""
try: try:
result = []
key_len = len(password) key_len = len(password)
result = []
for i in range(0, len(hex_data), 2): for i in range(0, len(hex_data), 2):
if i + 1 < len(hex_data): if i + 1 < len(hex_data):
hex_byte = hex_data[i:i+2] hex_byte = hex_data[i:i+2]
@@ -143,17 +163,28 @@ class EncryptionSystem:
return None return None
def generate_keys(self, save_path=None, key_password=None): def generate_keys(self, save_path=None, key_password=None):
"""
Generate a fresh set of encryption keys and save to a key file.
Args:
save_path: Path to save the key file (default: encryption.key).
key_password: Password to protect the key file.
Returns:
The password used, or None if generation failed.
"""
if key_password is None: if key_password is None:
key_password = input("请设置密钥文件密码: ") key_password = input("Set key file password: ")
confirm = input("请再次输入密码确认: ") confirm = input("Confirm password: ")
if key_password != confirm: if key_password != confirm:
print("❌ 密码不匹配") print("❌ Passwords do not match")
return None return None
print("=" * 60) print("=" * 60)
print("正在生成随机密钥...") print("Generating random keys...")
print("=" * 60) print("=" * 60)
# Generate all key components
self.upper_mapping = self._generate_random_alphabet(lowercase=False) self.upper_mapping = self._generate_random_alphabet(lowercase=False)
self.lower_mapping = self._generate_random_alphabet(lowercase=True) self.lower_mapping = self._generate_random_alphabet(lowercase=True)
self.digit_mapping = self._generate_random_digit_mapping() self.digit_mapping = self._generate_random_digit_mapping()
@@ -162,9 +193,11 @@ class EncryptionSystem:
self.long_key = self._generate_long_key(4096) self.long_key = self._generate_long_key(4096)
self.short_key = self._generate_short_key(512) self.short_key = self._generate_short_key(512)
# Build reverse mappings
self.digit_reverse = {v: k for k, v in self.digit_mapping.items()} self.digit_reverse = {v: k for k, v in self.digit_mapping.items()}
self.equal_reverse = {v: k for k, v in self.equal_mapping.items()} self.equal_reverse = {v: k for k, v in self.equal_mapping.items()}
# Bundle keys into a dictionary
keys_data = { keys_data = {
'upper_mapping': self.upper_mapping, 'upper_mapping': self.upper_mapping,
'lower_mapping': self.lower_mapping, 'lower_mapping': self.lower_mapping,
@@ -176,6 +209,7 @@ class EncryptionSystem:
'generated_at': datetime.now().isoformat() 'generated_at': datetime.now().isoformat()
} }
# Obfuscate and encrypt the key data
obfuscated = self._obfuscate_keys(keys_data) obfuscated = self._obfuscate_keys(keys_data)
encrypted = self._xor_encrypt_data(obfuscated, key_password) encrypted = self._xor_encrypt_data(obfuscated, key_password)
@@ -190,12 +224,17 @@ class EncryptionSystem:
self.keys_loaded = True self.keys_loaded = True
self._build_maps() self._build_maps()
print(f"✅ 密钥已生成并保存到: {save_path}") print(f"✅ Keys generated and saved to: {save_path}")
print("=" * 60) print("=" * 60)
return save_path return save_path
# ----------------------------------------------------------------------
# Internal helpers
# ----------------------------------------------------------------------
def _build_maps(self): def _build_maps(self):
"""Build encryption and decryption maps from shuffled alphabets."""
self.upper_original = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" self.upper_original = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
self.lower_original = "abcdefghijklmnopqrstuvwxyz" self.lower_original = "abcdefghijklmnopqrstuvwxyz"
@@ -208,13 +247,14 @@ class EncryptionSystem:
self.decrypt_map[self.lower_mapping[i]] = self.lower_original[i] self.decrypt_map[self.lower_mapping[i]] = self.lower_original[i]
def _load_keys(self, key_file, key_password): def _load_keys(self, key_file, key_password):
"""Load and decrypt keys from a key file."""
try: try:
with open(key_file, 'r') as f: with open(key_file, 'r') as f:
encrypted_data = f.read() encrypted_data = f.read()
decrypted = self._xor_decrypt_data(encrypted_data, key_password) decrypted = self._xor_decrypt_data(encrypted_data, key_password)
if decrypted is None: if decrypted is None:
print("❌ 密码错误") print("❌ Incorrect password")
self.keys_loaded = False self.keys_loaded = False
return return
@@ -235,17 +275,18 @@ class EncryptionSystem:
self._build_maps() self._build_maps()
self.keys_loaded = True self.keys_loaded = True
print(f"✅ 密钥已从 {key_file} 加载") print(f"✅ Keys loaded from {key_file}")
except Exception: except Exception:
print("❌ 加载失败") print("❌ Loading failed")
self.keys_loaded = False self.keys_loaded = False
def _ensure_printable(self, text): def _ensure_printable(self, text):
"""Force all characters into printable ASCII range (32-126)."""
result = [] result = []
for c in text: for c in text:
val = ord(c) val = ord(c)
if val == 124: if val == 124: # '|' is used as a separator, keep it
result.append('|') result.append('|')
elif val < 32 or val > 126: elif val < 32 or val > 126:
val = val % 95 + 32 val = val % 95 + 32
@@ -254,10 +295,25 @@ class EncryptionSystem:
result.append(c) result.append(c)
return ''.join(result) return ''.join(result)
def _mix_keys(self, user_password, target_length): # ----------------------------------------------------------------------
if not self.keys_loaded: # Key derivation
raise Exception("密钥未加载") # ----------------------------------------------------------------------
def _mix_keys(self, user_password, target_length):
"""
Mix the user password with the short key using bit operations and swaps.
Args:
user_password: User-provided password.
target_length: Desired output length.
Returns:
A mixed printable string.
"""
if not self.keys_loaded:
raise Exception("Keys not loaded")
# Interleave user password and short key
mixed = [] mixed = []
max_len = max(len(user_password), len(self.short_key)) max_len = max(len(user_password), len(self.short_key))
for i in range(max_len): for i in range(max_len):
@@ -266,6 +322,7 @@ class EncryptionSystem:
if i < len(self.short_key): if i < len(self.short_key):
mixed.append(ord(self.short_key[i])) mixed.append(ord(self.short_key[i]))
# Apply bit transformations
for i in range(len(mixed)): for i in range(len(mixed)):
if i % 3 == 0: if i % 3 == 0:
mixed[i] = (mixed[i] << 1) & 0xFF mixed[i] = (mixed[i] << 1) & 0xFF
@@ -274,12 +331,14 @@ class EncryptionSystem:
else: else:
mixed[i] = mixed[i] ^ 0x5A mixed[i] = mixed[i] ^ 0x5A
# Swap pairs
for i in range(0, len(mixed) - 3, 4): for i in range(0, len(mixed) - 3, 4):
mixed[i], mixed[i+3] = mixed[i+3], mixed[i] mixed[i], mixed[i+3] = mixed[i+3], mixed[i]
mixed[i+1], mixed[i+2] = mixed[i+2], mixed[i+1] mixed[i+1], mixed[i+2] = mixed[i+2], mixed[i+1]
mixed.reverse() mixed.reverse()
# Convert to printable characters
result = [] result = []
for x in mixed: for x in mixed:
if x < 32 or x > 126: if x < 32 or x > 126:
@@ -288,6 +347,7 @@ class EncryptionSystem:
result_str = ''.join(result) result_str = ''.join(result)
# Extend if needed by repeating with variations
if len(result_str) < target_length: if len(result_str) < target_length:
base_key = result_str base_key = result_str
final_key = base_key final_key = base_key
@@ -297,10 +357,10 @@ class EncryptionSystem:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
elif iteration % 3 == 1: elif iteration % 3 == 1:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
next_chunk = ''.join([chr((ord(c) + iteration) % 95 + 32) for c in next_chunk]) next_chunk = ''.join(chr((ord(c) + iteration) % 95 + 32) for c in next_chunk)
else: else:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
next_chunk = ''.join([chr((ord(c) ^ iteration) % 95 + 32) for c in next_chunk]) next_chunk = ''.join(chr((ord(c) ^ iteration) % 95 + 32) for c in next_chunk)
final_key += next_chunk final_key += next_chunk
iteration += 1 iteration += 1
result_str = final_key[:target_length] result_str = final_key[:target_length]
@@ -308,11 +368,18 @@ class EncryptionSystem:
return self._ensure_printable(result_str) return self._ensure_printable(result_str)
def _derive_final_key(self, user_password, text_length): def _derive_final_key(self, user_password, text_length):
"""
Derive a final encryption key from the user password and short key.
The process includes mixing, hex conversion, reversal, and extension.
"""
mixed_key = self._mix_keys(user_password, text_length * 2) mixed_key = self._mix_keys(user_password, text_length * 2)
hex_key = ''.join([f"{ord(c):02x}" for c in mixed_key]) # Convert to hex and reverse
hex_key = ''.join(f"{ord(c):02x}" for c in mixed_key)
reversed_hex = hex_key[::-1] reversed_hex = hex_key[::-1]
# Convert back to printable characters
final_key = [] final_key = []
for i in range(0, len(reversed_hex), 2): for i in range(0, len(reversed_hex), 2):
if i + 1 < len(reversed_hex): if i + 1 < len(reversed_hex):
@@ -327,6 +394,7 @@ class EncryptionSystem:
final_key_str = ''.join(final_key) final_key_str = ''.join(final_key)
# Extend if needed
if len(final_key_str) < text_length: if len(final_key_str) < text_length:
base_key = final_key_str base_key = final_key_str
iteration = 0 iteration = 0
@@ -335,19 +403,22 @@ class EncryptionSystem:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
elif iteration % 3 == 1: elif iteration % 3 == 1:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
next_chunk = ''.join([chr((ord(c) + iteration) % 95 + 32) for c in next_chunk]) next_chunk = ''.join(chr((ord(c) + iteration) % 95 + 32) for c in next_chunk)
else: else:
next_chunk = base_key[::-1] next_chunk = base_key[::-1]
next_chunk = ''.join([chr((ord(c) ^ iteration) % 95 + 32) for c in next_chunk]) next_chunk = ''.join(chr((ord(c) ^ iteration) % 95 + 32) for c in next_chunk)
final_key_str += next_chunk final_key_str += next_chunk
iteration += 1 iteration += 1
final_key_str = final_key_str[:text_length] final_key_str = final_key_str[:text_length]
final_key_str = self._ensure_printable(final_key_str) return self._ensure_printable(final_key_str)
return final_key_str # ----------------------------------------------------------------------
# Core encryption operations
# ----------------------------------------------------------------------
def _apply_flip(self, text): def _apply_flip(self, text):
"""Apply case-flipping based on the flip pattern."""
if self.flip_pattern is None: if self.flip_pattern is None:
return text return text
@@ -361,15 +432,16 @@ class EncryptionSystem:
return ''.join(result) return ''.join(result)
def _xor_encrypt_with_final_key(self, text, user_password): def _xor_encrypt_with_final_key(self, text, user_password):
"""XOR encrypt with the derived final key, returning hex."""
final_key = self._derive_final_key(user_password, len(text)) final_key = self._derive_final_key(user_password, len(text))
key_len = len(final_key) key_len = len(final_key)
result = [] return ''.join(
for i, char in enumerate(text): f"{ord(char) ^ ord(final_key[i % key_len]):02x}"
xor_result = ord(char) ^ ord(final_key[i % key_len]) for i, char in enumerate(text)
result.append(f"{xor_result:02x}") )
return ''.join(result)
def _xor_decrypt_with_final_key(self, hex_text, user_password): def _xor_decrypt_with_final_key(self, hex_text, user_password):
"""XOR decrypt with the derived final key."""
try: try:
text_length = len(hex_text) // 2 text_length = len(hex_text) // 2
final_key = self._derive_final_key(user_password, text_length) final_key = self._derive_final_key(user_password, text_length)
@@ -390,47 +462,35 @@ class EncryptionSystem:
return None return None
def _substitute_letters(self, text, mapping): def _substitute_letters(self, text, mapping):
result = [] """Apply a substitution map to letters."""
for char in text: return ''.join(mapping.get(char, char) for char in text)
if char in mapping:
result.append(mapping[char])
else:
result.append(char)
return ''.join(result)
def _encode_digit(self, num_str): def _encode_digit(self, num_str):
result = [] """Encode a digit string using the digit mapping."""
for char in num_str: return ''.join(self.digit_mapping.get(char, char) for char in num_str)
if char in self.digit_mapping:
result.append(self.digit_mapping[char])
else:
result.append(char)
return ''.join(result)
def _decode_digit(self, encoded_str): def _decode_digit(self, encoded_str):
result = [] """Decode a digit string using the reverse digit mapping."""
for char in encoded_str: return ''.join(self.digit_reverse.get(char, char) for char in encoded_str)
if char in self.digit_reverse:
result.append(self.digit_reverse[char])
else:
result.append(char)
return ''.join(result)
def _get_dynamic_key(self, text_length): def _get_dynamic_key(self, text_length):
"""Generate a dynamic key from the long key, repeated as needed."""
key = self.long_key key = self.long_key
while len(key) < text_length: if len(key) < text_length:
key += self.long_key repeats = (text_length // len(key)) + 1
key = (key * repeats)[:text_length]
return key[:text_length] return key[:text_length]
def _xor_encrypt_with_key(self, text, key): def _xor_encrypt_with_key(self, text, key):
"""XOR encrypt with a fixed key, returning hex."""
key_len = len(key) key_len = len(key)
result = [] return ''.join(
for i, char in enumerate(text): f"{ord(char) ^ ord(key[i % key_len]):02x}"
xor_result = ord(char) ^ ord(key[i % key_len]) for i, char in enumerate(text)
result.append(f"{xor_result:02x}") )
return ''.join(result)
def _xor_decrypt_with_key(self, hex_text, key): def _xor_decrypt_with_key(self, hex_text, key):
"""XOR decrypt with a fixed key."""
try: try:
key_len = len(key) key_len = len(key)
result = [] result = []
@@ -448,10 +508,28 @@ class EncryptionSystem:
except Exception: except Exception:
return None return None
def encrypt(self, plaintext, user_password): # ----------------------------------------------------------------------
if not self.keys_loaded: # Public API
return "❌ 错误:密钥未加载" # ----------------------------------------------------------------------
def encrypt(self, plaintext, user_password):
"""
Encrypt plaintext with the given password.
Workflow:
1. Base64 encode the plaintext.
2. Apply letter substitution and case-flipping.
3. Reverse the string and append padding count.
4. XOR encrypt with dynamic key (long key).
5. XOR encrypt with derived final key (user password + short key).
Returns:
Encrypted ciphertext as a hex string.
"""
if not self.keys_loaded:
return "❌ Error: Keys not loaded"
# Step 1: Base64 encode and handle special chars
b64 = base64.b64encode(plaintext.encode('utf-8')).decode('utf-8') b64 = base64.b64encode(plaintext.encode('utf-8')).decode('utf-8')
equal_count = b64.count('=') equal_count = b64.count('=')
@@ -460,33 +538,44 @@ class EncryptionSystem:
processed = processed.replace(old, new) processed = processed.replace(old, new)
processed = processed.rstrip('=') processed = processed.rstrip('=')
# Step 2: Letter substitution + flip + reverse
sub = self._substitute_letters(processed, self.encrypt_map) sub = self._substitute_letters(processed, self.encrypt_map)
flipped = self._apply_flip(sub) flipped = self._apply_flip(sub)
reversed_text = flipped[::-1] reversed_text = flipped[::-1]
# Step 3: Append padding count
equal_char = self.equal_mapping[str(equal_count)] equal_char = self.equal_mapping[str(equal_count)]
with_equal = f"{reversed_text}|{equal_char}" with_equal = f"{reversed_text}|{equal_char}"
# Step 4: Dynamic key (long key) encryption
key_length_str = str(len(with_equal)) key_length_str = str(len(with_equal))
key_length_encoded = self._encode_digit(key_length_str) key_length_encoded = self._encode_digit(key_length_str)
dynamic_key = self._get_dynamic_key(len(with_equal)) dynamic_key = self._get_dynamic_key(len(with_equal))
encrypted_by_dynamic = self._xor_encrypt_with_key(with_equal, dynamic_key) encrypted_by_dynamic = self._xor_encrypt_with_key(with_equal, dynamic_key)
# Step 5: Final encryption with derived key
combined = f"{encrypted_by_dynamic}|{key_length_encoded}" combined = f"{encrypted_by_dynamic}|{key_length_encoded}"
final_encrypted = self._xor_encrypt_with_final_key(combined, user_password) final_encrypted = self._xor_encrypt_with_final_key(combined, user_password)
return final_encrypted return final_encrypted
def decrypt(self, ciphertext, user_password): def decrypt(self, ciphertext, user_password):
"""
Decrypt ciphertext with the given password.
Returns:
The original plaintext, or an error message on failure.
"""
if not self.keys_loaded: if not self.keys_loaded:
return "❌ 解密失败" return "❌ Decryption failed"
try: try:
# Step 1: Decrypt with derived final key
combined = self._xor_decrypt_with_final_key(ciphertext, user_password) combined = self._xor_decrypt_with_final_key(ciphertext, user_password)
if combined is None: if combined is None:
return "❌ 解密失败" return "❌ Decryption failed"
# Step 2: Extract hex data and length indicator
if '|' in combined: if '|' in combined:
parts = combined.split('|') parts = combined.split('|')
if len(parts) >= 2: if len(parts) >= 2:
@@ -499,6 +588,7 @@ class EncryptionSystem:
hex_data = combined hex_data = combined
key_length_encoded = 'g' key_length_encoded = 'g'
# Step 3: Decode length and get dynamic key
key_length_str = self._decode_digit(key_length_encoded) key_length_str = self._decode_digit(key_length_encoded)
try: try:
key_length = int(key_length_str) key_length = int(key_length_str)
@@ -506,10 +596,13 @@ class EncryptionSystem:
key_length = 16 key_length = 16
dynamic_key = self._get_dynamic_key(key_length) dynamic_key = self._get_dynamic_key(key_length)
# Step 4: Decrypt with dynamic key
xor_decrypted = self._xor_decrypt_with_key(hex_data, dynamic_key) xor_decrypted = self._xor_decrypt_with_key(hex_data, dynamic_key)
if xor_decrypted is None: if xor_decrypted is None:
return "❌ 解密失败" return "❌ Decryption failed"
# Step 5: Extract main data and padding count
if '|' in xor_decrypted: if '|' in xor_decrypted:
main_part, equal_char = xor_decrypted.split('|') main_part, equal_char = xor_decrypted.split('|')
equal_count = int(self.equal_reverse.get(equal_char, '0')) equal_count = int(self.equal_reverse.get(equal_char, '0'))
@@ -517,192 +610,211 @@ class EncryptionSystem:
main_part = xor_decrypted main_part = xor_decrypted
equal_count = 0 equal_count = 0
# Step 6: Reverse, flip, substitute
reversed_text = main_part[::-1] reversed_text = main_part[::-1]
flipped = self._apply_flip(reversed_text) flipped = self._apply_flip(reversed_text)
sub = self._substitute_letters(flipped, self.decrypt_map) sub = self._substitute_letters(flipped, self.decrypt_map)
# Step 7: Restore Base64 special chars and padding
for old, new in self.special_decrypt.items(): for old, new in self.special_decrypt.items():
sub = sub.replace(old, new) sub = sub.replace(old, new)
b64_with_equal = sub + '=' * equal_count b64_with_equal = sub + '=' * equal_count
if len(b64_with_equal) % 4 != 0: if len(b64_with_equal) % 4 != 0:
return "❌ 解密失败" return "❌ Decryption failed"
# Step 8: Base64 decode
decoded = base64.b64decode(b64_with_equal.encode('utf-8')).decode('utf-8') decoded = base64.b64decode(b64_with_equal.encode('utf-8')).decode('utf-8')
return decoded return decoded
except Exception: except Exception:
return "❌ 解密失败" return "❌ Decryption failed"
def print_keys(self): def print_keys(self):
"""Display information about the currently loaded keys."""
if not self.keys_loaded: if not self.keys_loaded:
print("❌ 未加载密钥") print("❌ Keys not loaded")
return return
print("=" * 60) print("=" * 60)
print("密钥信息") print("Key Information")
print("=" * 60) print("=" * 60)
print(f"密钥文件: {self.key_file}") print(f"Key file: {self.key_file}")
print(f"大写映射表: {self.upper_mapping}") print(f"Uppercase mapping: {self.upper_mapping}")
print(f"小写映射表: {self.lower_mapping}") print(f"Lowercase mapping: {self.lower_mapping}")
print(f"翻转模式: {self.flip_pattern}") print(f"Flip pattern: {self.flip_pattern}")
print(f"长密钥长度: {len(self.long_key)} 位") print(f"Long key length: {len(self.long_key)} bits")
print(f"短密钥长度: {len(self.short_key)} 位") print(f"Short key length: {len(self.short_key)} bits")
print("=" * 60) print("=" * 60)
# ----------------------------------------------------------------------
# CLI Entry Point
# ----------------------------------------------------------------------
def main(): def main():
"""Command-line interface for the encryption system."""
print("=" * 60) print("=" * 60)
print("欢迎使用加密系统") print("Welcome to the Encryption System")
print("=" * 60) print("=" * 60)
crypto = None crypto = None
key_password = None key_password = None
# Try loading default key file
if os.path.exists("encryption.key"): if os.path.exists("encryption.key"):
key_password = input("请输入默认密钥文件 (encryption.key) 的密码: ") key_password = input("Enter password for default key file (encryption.key): ")
crypto = EncryptionSystem("encryption.key", key_password) crypto = EncryptionSystem("encryption.key", key_password)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
crypto = None crypto = None
else: else:
print("\n未找到默认密钥文件,请先生成") print("\nDefault key file not found. Please generate one first.")
choice = input("是否生成默认密钥文件?(y/n): ").strip().lower() choice = input("Generate default key file? (y/n): ").strip().lower()
if choice == 'y': if choice == 'y':
crypto = EncryptionSystem() crypto = EncryptionSystem()
key_password = crypto.generate_keys("encryption.key") result = crypto.generate_keys("encryption.key")
if key_password is None: if result is None:
print("❌ 生成失败") print("❌ Generation failed")
crypto = None crypto = None
else: else:
print("⚠️ 请使用模式4或5指定密钥文件,或模式6生成新密钥") print("⚠️ Use options 4, 5, or 6 to manage key files manually.")
# Main interaction loop
while True: while True:
print("\n请选择操作:") print("\nSelect an option:")
print("1. 使用默认密钥加密") print("1. Encrypt with default key")
print("2. 使用默认密钥解密") print("2. Decrypt with default key")
print("3. 生成新密钥(覆盖默认)") print("3. Generate new key (overwrite default)")
print("4. 使用指定密钥文件加密") print("4. Encrypt with custom key file")
print("5. 使用指定密钥文件解密") print("5. Decrypt with custom key file")
print("6. 生成密钥并保存到当前文件夹") print("6. Generate key and save to current folder")
print("7. 查看当前密钥信息") print("7. View current key info")
print("8. 退出") print("8. Exit")
choice = input("\n请选择操作 (1-8): ").strip() choice = input("\nEnter choice (1-8): ").strip()
if choice == '1': if choice == '1':
# Encrypt with default key
if crypto is None or not crypto.keys_loaded: if crypto is None or not crypto.keys_loaded:
if os.path.exists("encryption.key"): if os.path.exists("encryption.key"):
if key_password is None: if key_password is None:
key_password = input("请输入默认密钥文件密码: ") key_password = input("Enter default key file password: ")
crypto = EncryptionSystem("encryption.key", key_password) crypto = EncryptionSystem("encryption.key", key_password)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
continue continue
else: else:
print("❌ 密钥文件不存在") print("❌ Key file not found")
continue continue
password = input("请输入加密密码: ") password = input("Enter encryption password: ")
text = input("请输入要加密的文本: ") text = input("Enter text to encrypt: ")
if text and password: if text and password:
encrypted = crypto.encrypt(text, password) encrypted = crypto.encrypt(text, password)
print(f"\n✅ 加密结果: {encrypted}") print(f"\n✅ Encrypted result: {encrypted}")
elif choice == '2': elif choice == '2':
# Decrypt with default key
if crypto is None or not crypto.keys_loaded: if crypto is None or not crypto.keys_loaded:
if os.path.exists("encryption.key"): if os.path.exists("encryption.key"):
if key_password is None: if key_password is None:
key_password = input("请输入默认密钥文件密码: ") key_password = input("Enter default key file password: ")
crypto = EncryptionSystem("encryption.key", key_password) crypto = EncryptionSystem("encryption.key", key_password)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
continue continue
else: else:
print("❌ 密钥文件不存在") print("❌ Key file not found")
continue continue
password = input("请输入加密密码: ") password = input("Enter encryption password: ")
text = input("请输入要解密的密文: ") text = input("Enter ciphertext to decrypt: ")
if text and password: if text and password:
decrypted = crypto.decrypt(text, password) decrypted = crypto.decrypt(text, password)
print(f"\n✅ 解密结果: {decrypted}") print(f"\n✅ Decrypted result: {decrypted}")
elif choice == '3': elif choice == '3':
# Generate and overwrite default key
crypto = EncryptionSystem() crypto = EncryptionSystem()
key_password = crypto.generate_keys("encryption.key") result = crypto.generate_keys("encryption.key")
if key_password is None: if result is None:
print("❌ 生成失败") print("❌ Generation failed")
else: else:
print("✅ 默认密钥已更新") print("✅ Default key updated")
elif choice == '4': elif choice == '4':
key_file = input("请输入密钥文件路径: ") # Encrypt with custom key file
key_file = input("Enter key file path: ")
if not os.path.exists(key_file): if not os.path.exists(key_file):
print(f"❌ 文件不存在") print(f"❌ File not found: {key_file}")
continue continue
kp = input(f"请输入密钥文件密码: ") kp = input("Enter key file password: ")
crypto = EncryptionSystem(key_file, kp) crypto = EncryptionSystem(key_file, kp)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
continue continue
password = input("请输入加密密码: ") password = input("Enter encryption password: ")
text = input("请输入要加密的文本: ") text = input("Enter text to encrypt: ")
if text and password: if text and password:
encrypted = crypto.encrypt(text, password) encrypted = crypto.encrypt(text, password)
print(f"\n✅ 加密结果: {encrypted}") print(f"\n✅ Encrypted result: {encrypted}")
elif choice == '5': elif choice == '5':
key_file = input("请输入密钥文件路径: ") # Decrypt with custom key file
key_file = input("Enter key file path: ")
if not os.path.exists(key_file): if not os.path.exists(key_file):
print(f"❌ 文件不存在") print(f"❌ File not found: {key_file}")
continue continue
kp = input(f"请输入密钥文件密码: ") kp = input("Enter key file password: ")
crypto = EncryptionSystem(key_file, kp) crypto = EncryptionSystem(key_file, kp)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
continue continue
password = input("请输入加密密码: ") password = input("Enter encryption password: ")
text = input("请输入要解密的密文: ") text = input("Enter ciphertext to decrypt: ")
if text and password: if text and password:
decrypted = crypto.decrypt(text, password) decrypted = crypto.decrypt(text, password)
print(f"\n✅ 解密结果: {decrypted}") print(f"\n✅ Decrypted result: {decrypted}")
elif choice == '6': elif choice == '6':
# Generate new key with timestamp
timestamp = int(time.time()) timestamp = int(time.time())
filename = f"key_{timestamp}.key" filename = f"key_{timestamp}.key"
crypto = EncryptionSystem() crypto = EncryptionSystem()
kp = crypto.generate_keys(filename) result = crypto.generate_keys(filename)
if kp is None: if result is None:
print("❌ 生成失败") print("❌ Generation failed")
else: else:
print(f"✅ 密钥已保存到: {filename}") print(f"✅ Key saved to: {filename}")
elif choice == '7': elif choice == '7':
# Show key info
if crypto is None or not crypto.keys_loaded: if crypto is None or not crypto.keys_loaded:
if os.path.exists("encryption.key"): if os.path.exists("encryption.key"):
if key_password is None: if key_password is None:
key_password = input("请输入默认密钥文件密码: ") key_password = input("Enter default key file password: ")
crypto = EncryptionSystem("encryption.key", key_password) crypto = EncryptionSystem("encryption.key", key_password)
if not crypto.keys_loaded: if not crypto.keys_loaded:
print("❌ 加载失败") print("❌ Loading failed")
continue continue
else: else:
print("❌ 未加载密钥") print("❌ Keys not loaded")
continue continue
crypto.print_keys() crypto.print_keys()
elif choice == '8': elif choice == '8':
print("感谢使用,再见!") print("Goodbye!")
break break
else: else:
print("❌ 无效选择") print("❌ Invalid choice")
if __name__ == "__main__": if __name__ == "__main__":
main() main()