简单即时通讯系统实现(课程设计)(python)

本代码成功实现了一个安全的多客户端即时聊天应用程序,采用了对称加密(使用Fernet库)和SHA-256哈希算法来保护通信的机密性和完整性。

服务器端负责监听客户端的连接请求,一旦有两个客户端连接成功,就为每个客户端创建一个独立的线程。这些线程负责接收、解密和转发消息。

在消息传输过程中,使用哈希算法验证以确保消息未被篡改。

这种设计保证了消息的机密性和完整性,使得即时聊天更加安全可靠。此外,代码还提供了可扩展性,可以根据实际需求进一步增加功能和改进安全性。

在运行代码前要先打开cmd安装pycryptodome库

pip install pycryptodome

生成密钥的代码 

from cryptography.fernet import Fernet
 
# 生成Fernet密钥
new_key = Fernet.generate_key()
 
# 将新密钥保存到文件
with open("./des_bkey.bin", "wb") as key_file:
    key_file.write(new_key)
 
# 生成Fernet密钥
new_key = Fernet.generate_key()
 
# 将新密钥保存到文件
with open("./des_akey.bin", "wb") as key_file:
    key_file.write(new_key)

生成AB密钥的代码(a,b自己改一下)

from cryptography.fernet import Fernet

# 生成Fernet密钥
a_private_key = Fernet.generate_key()

# 将相同的密钥赋值给public_keyb变量
public_keya = a_private_key

# 将密钥写入文件
with open("a_private_key.key", "wb") as private_key_file:
    private_key_file.write(a_private_key)

with open("public_keya.key", "wb") as public_key_file:
    public_key_file.write(public_keya)

print("Keys have been saved to b_private_key.key and public_keyb.key")

重点:运行代码时要先运行主机端代码,再运行客户端B代码,最后运行客户端A代码

以下是主机端代码

import socket
import threading
from cryptography.fernet import Fernet
import hashlib

# 加载a和b的共享密钥
with open("D:/pythondm/des_akey.bin", "rb") as file:
    a1 = file.read()

with open("D:/pythondm/des_bkey.bin", "rb") as file:
    b1 = file.read()

# 创建a到b的加密套件
a_to_b_cipher = Fernet(a1)

# 创建b到a的加密套件
b_to_a_cipher = Fernet(b1)

# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'
port = 1235
server_socket.bind((host, port))
server_socket.listen(2)  # 监听两个客户端连接
print(f"等待客户端连接在 {host}:{port}")

clients = []

def sha256_hash(message):
    sha256 = hashlib.sha256()
    sha256.update(message.encode())
    return sha256.hexdigest()

def sign_message(message):
    # 进行哈希值计算
    signature = hashlib.sha256(message.encode()).hexdigest()
    return signature

def verify_signature(message, signature):
    # 验证哈希值
    calculated_signature = hashlib.sha256(message.encode()).hexdigest()
    return calculated_signature == signature

def forward_message(sender_socket, receiver_cipher):
    while True:
        try:
            encrypted_message = sender_socket.recv(1024)
            if not encrypted_message:
                break

            # 解密消息
            decrypted_message = receiver_cipher.decrypt(encrypted_message).decode()
            print(f"收到消息: {decrypted_message}")

            # 发送消息给接收者
            receiver_socket = clients[1 - clients.index(sender_socket)]

            # 根据消息的来源选择正确的加密密钥
            if sender_socket == clients[0]:
                sender_cipher = a_to_b_cipher
            else:
                sender_cipher = b_to_a_cipher

            # 数字签名
            signature = sign_message(decrypted_message)

            # 将消息和哈希值一起加密并发送
            message_with_signature = f"{decrypted_message}:{signature}"
            encrypted_message = sender_cipher.encrypt(message_with_signature.encode())
            receiver_socket.send(encrypted_message)

        except Exception as e:
            print(f"错误: {e}")
            break

while True:
    # 接受客户端连接
    client_socket, client_address = server_socket.accept()
    print(f"连接来自 {client_address} 的客户端")
    clients.append(client_socket)

    # 当有两个客户端连接时,为每个客户端创建一个线程
    if len(clients) == 2:
        client1_thread = threading.Thread(target=forward_message, args=(clients[0], b_to_a_cipher))
        client2_thread = threading.Thread(target=forward_message, args=(clients[1], a_to_b_cipher))
        client1_thread.daemon = True
        client2_thread.daemon = True
        client1_thread.start()
        client2_thread.start()

客户端A代码

import socket
import threading
from cryptography.fernet import Fernet
import hashlib

# 加载共享密钥a1
with open("D:/pythondm/des_akey.bin", "rb") as file:
    shared_key_a = file.read()

# 创建b_to_a加密套件
b_to_a_cipher = Fernet(shared_key_a)

# 与服务器建立连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'
port = 1235
client_socket.connect((host, port))

def sha256_hash(message):
    sha256 = hashlib.sha256()
    sha256.update(message.encode())
    return sha256.hexdigest()

def sign_message(message):
    signature = hashlib.sha256(message.encode()).hexdigest()
    return signature

def verify_signature(message, signature):
    calculated_signature = hashlib.sha256(message.encode()).hexdigest()
    return calculated_signature == signature

def receive_messages():
    while True:
        try:
            encrypted_message = client_socket.recv(1024)
            decrypted_message = b_to_a_cipher.decrypt(encrypted_message).decode()
            
            # 拆分消息和签名
            message, received_signature = decrypted_message.rsplit(':', 1)
            
            # 验证消息的签名
            if verify_signature(message, received_signature):
                print(f"客户端B: {message}")
            else:
                print("接收到篡改的消息!")
        except Exception as e:
            print(f"错误: {e}")
            break

# 创建消息接收线程
receive_thread = threading.Thread(target=receive_messages)
receive_thread.daemon = True
receive_thread.start()

while True:
    message = input("客户端A: ")
    # 哈希值计算
    signature = sign_message(message)

    # 将消息和哈希值一起加密并发送
    message_with_signature = f"{message}:{signature}"
    encrypted_message = b_to_a_cipher.encrypt(message_with_signature.encode())
    client_socket.send(encrypted_message)

客户端B代码

import socket
import threading
from cryptography.fernet import Fernet
import hashlib

# 加载共享密钥b1
with open("D:/pythondm/des_bkey.bin", "rb") as file:
    shared_key_b = file.read()

# 创建a_to_b加密套件
a_to_b_cipher = Fernet(shared_key_b)

# 与服务器建立连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'
port = 1235
client_socket.connect((host, port))

def sha256_hash(message):
    sha256 = hashlib.sha256()
    sha256.update(message.encode())
    return sha256.hexdigest()

def sign_message(message):
    signature = hashlib.sha256(message.encode()).hexdigest()
    return signature

def verify_signature(message, signature):
    calculated_signature = hashlib.sha256(message.encode()).hexdigest()
    return calculated_signature == signature

def receive_messages():
    while True:
        try:
            encrypted_message = client_socket.recv(1024)
            decrypted_message = a_to_b_cipher.decrypt(encrypted_message).decode()
            
            # 拆分消息和签名
            message, received_signature = decrypted_message.rsplit(':', 1)
            
            # 验证消息的签名
            if verify_signature(message, received_signature):
                print(f"客户端A: {message}")
            else:
                print("接收到篡改的消息!")
        except Exception as e:
            print(f"错误: {e}")
            break

# 创建消息接收线程
receive_thread = threading.Thread(target=receive_messages)
receive_thread.daemon = True
receive_thread.start()

while True:
    message = input("客户端B: ")
    # 哈希值计算
    signature = sign_message(message)

    # 将消息和哈希值一起加密并发送
    message_with_signature = f"{message}:{signature}"
    encrypted_message = a_to_b_cipher.encrypt(message_with_signature.encode())
    client_socket.send(encrypted_message)

如果生成密钥有问题,就直接用我给的

a_private_key.key
NzHjn4Em974MZVnKC-mC9fTKUo9898ToRm1vM3i1Z-M=
b_private_key.key
OtsUYQW4Ym-zewNDL6KhzyUIHInN9Kblwubn6LFxTVQ=
des_akey.bin
cYQ2KCOHuVw3GDwa_7FABPXIqLW5CedgOcpGfNXjiwM=
des_bkey.bin
W9lIxjJ3Ki_lZyTBXSDxgpvKc0gVSjesn2UANVTauso=
public_keya.key
NzHjn4Em974MZVnKC-mC9fTKUo9898ToRm1vM3i1Z-M=
public_keyb.key
OtsUYQW4Ym-zewNDL6KhzyUIHInN9Kblwubn6LFxTVQ=

运行过程

先启动主机端

启动客户端b

启动客户端a

b端输入

可以在主机端和a端看到

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值