优点
1. 点对点(P2P)加密通信:
• 采用点对点通信模式,消息直接在客户端之间传输,无需通过中央服务器。
• 提高隐私性,避免中央服务器成为单点故障或攻击目标。
• 降低通信延迟,消息传输更高效。
2. 强大的加密机制:
• 使用 AES(高级加密标准)对消息进行加密,确保通信内容的安全性。
• 每个会话生成唯一的加密密钥,确保密钥的安全性。
• 使用 AES 的 EAX 模式,支持加密和消息认证,防止消息被篡改。
3. 临时数据存储:
• 聊天记录和用户信息仅在本地临时保存,且数据会在 48 小时后自动清除。
• 避免长期存储敏感数据,降低数据泄露风险。
• 适合需要临时通信的场景,如一次性会议或短期项目。
4. 管理员模式:
• 支持管理员模式,管理员可以重置用户信息和窃听所有消息。
• 为管理员提供更高的控制权限,便于管理用户和监控通信。
• 适合团队协作或小型组织使用。
5. 私信功能:
• 支持私信功能,用户可以通过 @用户名 的方式向特定用户发送私密消息。
• 方便用户进行一对一私密聊天,提升沟通效率。
• 私信内容同样使用 AES 加密,确保私密性。
6. 轻量级和跨平台:
• 程序轻量级,基于 Python 实现,支持跨平台运行。
• 使用标准库和少量第三方库,易于部署和使用。
• 支持 Windows、Linux 和 macOS 等操作系统。
7. 开源和可定制:
• 代码开源,用户可以根据需求进行定制和扩展。
• 提供完整的源代码,用户可以自由修改和优化。
• 适合开发者学习和二次开发。
8. 剪贴板集成:
• 收到的消息会自动复制到剪贴板,方便用户快速粘贴使用。
• 提升用户体验,减少手动复制操作。
实用性亮点
1. 隐私保护:
• 通过点对点加密通信和临时数据存储,确保用户隐私不被泄露。
• 适合对隐私要求极高的场景,如机密会议或敏感信息交流。
2. 管理员功能:
• 管理员可以重置用户信息和窃听所有消息,便于管理和监控通信。
• 适合团队协作或小型组织使用。
3. 私信模式:
• 支持一对一私密聊天,提升沟通效率。
• 私信内容同样使用 AES 加密,确保私密性。
4. 跨平台支持:
• 支持 Windows、Linux 和 macOS 等操作系统,用户可以在不同平台上使用。
5. 临时数据存储:
• 聊天记录和用户信息仅在本地临时保存,且数据会在 48 小时后自动清除。
• 避免长期存储敏感数据,降低数据泄露风险。
6. 轻量级和易于部署:
• 程序轻量级,使用标准库和少量第三方库,易于部署和使用。
• 适合快速搭建和使用。
7. 开源和可定制:
• 代码开源,用户可以根据需求进行定制和扩展。
• 适合开发者学习和二次开发。
适用场景
1. 小型团队协作:
• 适合小规模团队进行内部沟通,管理员模式便于管理。
2. 临时会议:
• 临时数据存储机制适合一次性会议或短期项目。
3. 隐私需求高的场景:
• P2P 加密通信和临时存储机制适合对隐私要求极高的场景。
4. 开发者学习和二次开发:
• 代码开源,适合开发者学习和二次开发。
总结
该代码在 隐私保护、管理员功能、私信模式、跨平台支持 和 临时数据存储 等方面具有显著优势,适合对隐私要求高、需要临时通信或团队协作的场景。同时,代码开源且易于定制,适合开发者学习和二次开发。
import socket
import threading
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Protocol.KDF import PBKDF2 # 引入 PBKDF2
import pyperclip # 用于复制粘贴功能
import json
import os
import time# 保存数据的文件名
DATA_FILE = "C:\\chat_data.json"# 生成加密密钥
def generate_key():
return get_random_bytes(16)# 派生密钥
def derive_key(password, salt):
return PBKDF2(password, salt, dkLen=32, count=100000) # 使用 PBKDF2 派生密钥# 加密消息
def encrypt_message(key, message):
cipher = AES.new(key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(message.encode("utf-8")) # 将消息编码为字节
return nonce + ciphertext + tag# 解密消息
def decrypt_message(key, encrypted_message):
nonce = encrypted_message[:16]
ciphertext = encrypted_message[16:-16]
tag = encrypted_message[-16:]
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return plaintext.decode("utf-8") # 将字节解码为字符串# 加密保存数据
def encrypt_data(key, data):
cipher = AES.new(key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(json.dumps(data).encode("utf-8"))
return nonce + ciphertext + tag# 解密加载数据
def decrypt_data(key, encrypted_data):
nonce = encrypted_data[:16]
ciphertext = encrypted_data[16:-16]
tag = encrypted_data[-16:]
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return json.loads(plaintext.decode("utf-8"))# 保存数据到文件
def save_data(username, chat_history):
data = {
"username": username,
"chat_history": chat_history,
"timestamp": time.time() # 记录保存时间
}
# 生成加密密钥
key = generate_key()
# 加密数据
encrypted_data = encrypt_data(key, data)
# 保存加密数据到文件
with open(DATA_FILE, "wb") as f:
f.write(key + encrypted_data)# 加载数据
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "rb") as f:
encrypted_data = f.read()
# 提取密钥和加密数据
key = encrypted_data[:16]
encrypted_data = encrypted_data[16:]
# 解密数据
data = decrypt_data(key, encrypted_data)
# 检查是否超过48小时
if time.time() - data["timestamp"] <= 48 * 3600:
return data["username"], data["chat_history"]
# 如果文件不存在或数据过期,则清除数据
if os.path.exists(DATA_FILE):
os.remove(DATA_FILE)
return None, []# 清理所有数据
def clear_data():
if os.path.exists(DATA_FILE):
os.remove(DATA_FILE)
print("已清理所有本地数据。")class P2PClient:
def __init__(self, host='127.0.0.1', port=12345):
self.host = host
self.port = port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 加载数据
self.username, self.chat_history = load_data()
if not self.username:
self.username = input("请输入你的用户名: ")
# 检查用户名是否为 admin757
if self.username == "admin757":
self.admin_mode = True
print("你已进入管理员模式。")
self.peers = {} # 记录其他客户端:{peer_socket: (username, key)}
self.lock = threading.Lock()
self.admin_mode = False # 管理员模式
self.listen_mode = False # 窃听模式
self.private_mode = False # 私信模式
self.private_target = None # 私信对象def start(self):
try:
# 启动监听线程
listen_thread = threading.Thread(target=self.listen_for_connections)
listen_thread.start()# 连接到其他客户端
self.connect_to_peer()# 发送消息
self.send_messages()
except Exception as e:
print(f"启动客户端失败: {e}")
finally:
# 退出时保存数据
save_data(self.username, self.chat_history)
# 清理
self.cleanup()
self.client_socket.close()def listen_for_connections(self):
try:
self.client_socket.bind((self.host, self.port))
self.client_socket.listen(5)
print(f"正在监听 {self.host}:{self.port}...")while True:
peer_socket, addr = self.client_socket.accept()
print(f"新连接来自 {addr}")# 接收对方的用户名
username = peer_socket.recv(1024).decode("utf-8")
print(f"{username} 加入了聊天。")# 生成加密密钥并发送给对方
key = generate_key()
peer_socket.send(key)# 记录对方客户端
with self.lock:
self.peers[peer_socket] = (username, key)# 启动线程处理对方的消息
peer_thread = threading.Thread(target=self.handle_peer, args=(peer_socket,))
peer_thread.start()
except Exception as e:
print(f"监听连接失败: {e}")def connect_to_peer(self):
try:
# 连接到其他客户端
peer_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
peer_socket.connect((self.host, self.port))# 发送自己的用户名
peer_socket.send(self.username.encode("utf-8"))# 接收对方的加密密钥
key = peer_socket.recv(1024)# 记录对方客户端
with self.lock:
self.peers[peer_socket] = (self.username, key)# 启动线程处理对方的消息
peer_thread = threading.Thread(target=self.handle_peer, args=(peer_socket,))
peer_thread.start()
except Exception as e:
print(f"连接失败: {e}")def handle_peer(self, peer_socket):
try:
while True:
encrypted_message = peer_socket.recv(4096)
if not encrypted_message:
break# 解密消息
username, key = self.peers[peer_socket]
try:
message = decrypt_message(key, encrypted_message)
except Exception as e:
print(f"解密消息失败: {e}")
continue# 判断是否是退出指令
if message == "/exit":
self.cleanup_peer(peer_socket, username)
break# 判断是否是私信
if message.startswith("[私信]"):
try:
# 显示私信,使用对方用户名
print(f"{username} {message}")
self.chat_history.append(f"{username} {message}")
except Exception as e:
print(f"解码私信失败: {e}")
else:
# 在私信模式下,屏蔽广播消息
if not self.private_mode:
try:
# 显示广播消息,使用对方用户名
print(f"{username}: {message}")
self.chat_history.append(f"{username}: {message}")
except Exception as e:
print(f"解码广播消息失败: {e}")
pyperclip.copy(message) # 将消息复制到剪贴板
except Exception as e:
print(f"处理对方消息失败: {e}")
finally:
# 对方断开连接
self.cleanup_peer(peer_socket, username)def send_messages(self):
while True:
message = input()
if message.lower() == "exit":
break# 判断是否是重置命令
if message.startswith("重置用户") and self.admin_mode:
target_username = message.split()[1]
self.reset_user(target_username)
continue# 判断是否是窃听命令
if message == "窃听所有消息" and self.admin_mode:
self.listen_mode = True
print("已开启窃听模式。")
continue# 判断是否是清理命令
if message == "709@":
clear_data()
self.username = input("请输入新的用户名: ")
self.chat_history = []
continue# 判断是否是私信
if message.startswith("@"):
target_username = message.split()[0][1:] # 提取目标用户名
if self.private_mode:
# 切换私信对象
self.private_target = target_username
print(f"已切换到与 {target_username} 的私信模式。")
else:
# 进入私信模式
self.private_mode = True
self.private_target = target_username
print(f"已进入与 {target_username} 的私信模式。")
continue# 判断是否是退出私信模式
if message == "/退出私信模式":
self.private_mode = False
self.private_target = None
print("已退出私信模式。")
continue# 私信模式
if self.private_mode:
if self.private_target:
# 发送私信
private_message = f"[私信] {self.username}: {message}"
self.send_to_user(self.private_target, private_message)
else:
print("错误:未选择私信对象。")
else:
# 发送广播消息
self.send_to_all_peers(message)def send_to_all_peers(self, message):
with self.lock:
for peer_socket, (_, key) in self.peers.items():
try:
encrypted_message = encrypt_message(key, message)
peer_socket.send(encrypted_message)
except Exception as e:
print(f"发送消息失败: {e}")def send_to_user(self, target_username, message):
with self.lock:
target_found = False
for peer_socket, (username, key) in self.peers.items():
# 忽略大小写匹配用户名
if username.lower() == target_username.lower():
try:
# 加密消息
encrypted_message = encrypt_message(key, message)
# 发送消息
peer_socket.send(encrypted_message)
print(f"私信已发送给 {username}。")
target_found = True
break
except Exception as e:
print(f"发送私信失败: {e}")
break
if not target_found:
print(f"错误:用户 {target_username} 不存在或未连接。")def reset_user(self, target_username):
with self.lock:
for peer_socket, (username, key) in self.peers.items():
if username == target_username:
try:
# 发送重置指令
reset_message = encrypt_message(key, "/reset")
peer_socket.send(reset_message)
print(f"已重置用户 {username} 的聊天记录和用户名。")
break
except Exception as e:
print(f"重置用户失败: {e}")
else:
print(f"错误:用户 {target_username} 不存在。")def cleanup_peer(self, peer_socket, username):
with self.lock:
if peer_socket in self.peers:
# 清除对方记录
self.peers.pop(peer_socket)
print(f"{username} 离开了聊天。")
peer_socket.close()def cleanup(self):
with self.lock:
# 发送退出指令给所有对方客户端
for peer_socket, (_, key) in self.peers.items():
try:
peer_socket.send(encrypt_message(key, "/exit"))
except Exception as e:
print(f"发送退出指令失败: {e}")
# 清除所有记录
self.peers.clear()
print("已清理所有记录并退出。")if __name__ == "__main__":
client = P2PClient()
client.start()