本文已参与「新人创作礼」活动,一起开启掘金创作之路。
基于DES和RSA算法的自动分配密钥加密聊天程序
要求
- 实现密钥自动生成,并基于RSA算法进行密钥共享。
- 要求程序能够实现基于DES加密的全双工通信,并且加密过程对用户是透明的。
代码
server.py
import rsa
import socket
import threading
import pickle
import sys
import pyDes
import time
Des_Key = b'qwerasdf'
Des_IV = b"\x00\x00\x00\x00\x00\x00\x00\x00"
PORT = 4396
BUFF = 1024
def DesEncrypt(str):
k=pyDes.des(Des_Key,pyDes.CBC,Des_IV,pad=None,padmode=pyDes.PAD_PKCS5)
Encrypt_Str = k.encrypt(str)
return Encrypt_Str
def DesDecrypt(str):
k = pyDes.des(Des_Key, pyDes.CBC, Des_IV, pad = None, padmode = pyDes.PAD_PKCS5)
Decrypt_Str = k.decrypt(str)
return Decrypt_Str
def SendMessage(Sock, test):
while True:
SendData = input("")
if SendData == "exit":
Sock.close()
encryptdata = DesEncrypt(SendData)
print('加密数据:(' + str(encryptdata)+')')
if len(SendData) > 0:
Sock.send(encryptdata)
def RecvMessage(Sock, test):
while True:
Message = Sock.recv(BUFF)
decryptdata = DesDecrypt(Message)
if len(Message)>0:
print("接收到消息:" + decryptdata.decode('utf8'))
#接收RSA公钥
def RecvRsaPub(Sock):
Message = Sock.recv(BUFF)
PubKey = pickle.loads(Message)
return PubKey
#发送DES密钥
def SendDesKey(Sock, PubKey):
content = Des_Key
Encrypt_Str = rsa.encrypt(content, PubKey)
Message = pickle.dumps([Encrypt_Str,Des_IV])
Sock.send(Message)
return 1
def main():
ServerSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ServerSock.bind(('127.0.0.1',PORT))
ServerSock.listen(5)
print("listening........")
while True:
ConSock,addr = ServerSock.accept()
print('connection succeed' + '\n' + 'you can chat online')
print("正在接收RSA公钥........")
time.sleep(1)
PubKey = RecvRsaPub(ConSock)
print("成功接收RSA公钥")
#print(PubKey)
if PubKey:
print("正在发送DES密钥........")
e = SendDesKey(ConSock, PubKey)
time.sleep(1)
print("成功发送DES密钥")
print("---------加密会话----------")
if e:
thread_1 = threading.Thread(target = SendMessage, args = (ConSock, None))
thread_2 = threading.Thread(target = RecvMessage, args = (ConSock, None))
thread_1.start()
thread_2.start()
if __name__ == '__main__':
main()
client.py
import rsa
import socket
import threading
import pickle
import sys
import pyDes
import time
#Des_Key = b'qwerasdf'
#Des_IV = b"\x00\x00\x00\x00\x00\x00\x00\x00"
PORT = 4396
BUFF = 1024
def DesEncrypt(str, Des_Key, Des_IV):
k=pyDes.des(Des_Key,pyDes.CBC,Des_IV,pad=None,padmode=pyDes.PAD_PKCS5)
Encrypt_Str = k.encrypt(str)
return Encrypt_Str
def DesDecrypt(str, Des_Key, Des_IV):
k = pyDes.des(Des_Key, pyDes.CBC, Des_IV, pad = None, padmode = pyDes.PAD_PKCS5)
Decrypt_Str = k.decrypt(str)
return Decrypt_Str
def SendMessage(Sock, Des_Key, Des_IV):
try:
while True:
SendData = input("")
if SendData == "exit":
Sock.close()
encryptdata = DesEncrypt(SendData, Des_Key, Des_IV)
print('加密数据:(' + str(encryptdata)+')')
if len(SendData) > 0:
Sock.send(encryptdata)
except:
return
else:
return
def RecvMessage(Sock, Des_Key, Des_IV):
while True:
Message = Sock.recv(BUFF)
decryptdata = DesDecrypt(Message, Des_Key, Des_IV)
if len(Message)>0:
print("接收到消息:" + decryptdata.decode('utf8'))
#RSA公私钥生成
def rsaCreate():
(PubKey, PrivateKey) = rsa.newkeys(512)
return (PubKey, PrivateKey)
#发送公钥
def SendRSAPub(Sock, PubKey):
#print(Pb)
data = pickle.dumps(PubKey)
Sock.send(data)
return 1
def RsaDecrypt(str, PrivateKey):
Decrypt_Str = rsa.decrypt(str, PrivateKey)
Decrypt_Str_1 = Decrypt_Str.decode('utf8')
return Decrypt_Str_1
#接收Des密钥
def RecvDesKey(Sock, PrivateKey):
Message = Sock.recv(BUFF)
#print(Des_Key)
(enDesKey,Des_IV) = pickle.loads(Message)
Des_Key = RsaDecrypt(enDesKey, PrivateKey)
Des_Key = Des_Key.encode('utf-8')
return (Des_Key,Des_IV)
def main():
ClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ServerAddr = "127.0.0.1"
#input("please input the server's ip address:")
ClientSock.connect((ServerAddr, PORT))
print('connection succeed, chat start!')
(PubKey, PrivateKey) = rsaCreate()
print("正在发送RSA公钥........")
k = SendRSAPub(ClientSock, PubKey)
time.sleep(1)
print("成功发送RSA公钥")
if k:
print("正在接收DES密钥........")
time.sleep(1)
(Des_Key,Des_IV) = RecvDesKey(ClientSock, PrivateKey)
print("成功接收DES密钥")
#print(Des_Key,Des_IV)
print("---------加密会话----------")
if Des_Key:
thread_3 = threading.Thread(target = SendMessage, args = (ClientSock, Des_Key, Des_IV))
thread_4 = threading.Thread(target = RecvMessage, args = (ClientSock, Des_Key, Des_IV))
thread_3.start()
thread_4.start()
if __name__ == '__main__':
main()
演示
服务端:
客户端:
过程分析
首先服务器端保存DES密钥,客户端生成RSA公私钥
客户端向服务器端发送RSA公钥
服务器端接收RSA公钥,并将DES密钥使用RSA公钥加密之后,发送给客户端
客户端接收到RSA加密之后的DES密钥,并使用自己的私钥解密,从而实现DES密钥的加密传输
此时使用多线程,发送和接收消息,双方加密会话
参考: