基于DES和RSA算法的自动分配密钥加密聊天程序

141 阅读2分钟

​本文已参与「新人创作礼」活动,一起开启掘金创作之路。

基于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密钥的加密传输

此时使用多线程,发送和接收消息,双方加密会话


参考:

github.com/beglage/RSA…