socket 服务端发送数据大于客户端接收速度_python+socket+DES实现加密通信

一、概述

Socket编程,将DES加密算法应用到网络通信,使用RSA算法自动分配密钥,设计好界面,可验证自动生成的密钥和加解密的正确结果。

二、功能需求

  1. 客户端和服务器建立连接后,客户端生成一个随机DES密钥
  2. 服务器端生成一个随机的RSA公私钥对,并将公钥发给客户端
  3. 客户端收到公钥后加密DES密钥,发给服务器,服务器用私钥解密
  4. 客户端和服务器使用DES密钥通信,进行聊天会话

三、总体设计

3.1 设计思想

  1. 利用Socket建立服务端和客户端的连接
  2. 实现服务端和客户端的简单会话,能发送数据和接收数据
  3. 服务端生成一个RSA公私钥对,并把公钥发送给客户端
  4. 客户端利用接收到的公钥对DES密钥进行加密,然后发给服务端
  5. 服务端利用私钥对加密后的DES密钥进行解密,即得到了DES密钥
  6. 发送端将数据先用DES加密,然后转化为utf-8格式,接收端将utf-8格式转为字符,然后再用DES解密,显示出来
  7. 利用threading多线程实现服务端和客户端能同时发送和接收数据

3.2 总体架构

9cc0ddecb0b536411157be8bf0ac9266.png
图3.1 程序总体架构图

3.3 开发环境

操作系统为Windows 10 企业版,64位操作系统。实现语言为Python 3.7.0,实验平台为Jupyter Notebook。

四、详细设计

  1. 服务端,创建Socket对象,绑定地址(host, port)到套接字,开始 TCP 监听,最大连接数量为5,等待连接;客户端,创建Socket对象,建立与服务器的连接。
  2. 利用recv()和send()函数来接收和发送数据,再加上while True实现服务端和客户端的简单会话,简单测试,结果正确进行下一步
  3. 客户端发送‘changekey’开始进行密钥交换,服务端收到消息后,利用RSA,产生一对公钥和私钥,并将公钥发送给客户端,客户端收到消息后,用公钥对DES密钥进行加密,并将加密结果发送给服务端,服务端收到消息后,用私钥进行解密,即得到了DES密钥
  4. 服务端和客户端进行聊天交互,首先判断key是否为0,为0则等待客户端发送密钥交换指令,不为0则正常通信。正常通信流程为,发送端将数据先用DES加密,然后转化为utf-8格式,接收端将utf-8格式转为字符,然后再用DES解密,显示出来。简单测试,结果正确进行下一步。
  5. 最后利用threading实现发送和接收的同时进行。客户端,首先判断key是否为0,然后调用一个线程用来接收消息,最后在当前线程进行发送消息;客户端,首先进行交换密钥,然后调用一个线程用来发送消息,最后在当前线程进行接收消息。当接收到的信息为‘quit’时,关闭套接字。

五、测试

5.1 环境

Python 3.7.0 & Jupyter Notebook

5.2 测试方案

采用有意义的英文句子作为明文输出,输出算法配置参数,和中间的加密结果以及解密结果。

5.3 测试结果

服务器端初始化

0065892ddabe7a6bb245224a422b8793.png

客户端和服务器端交换密钥

1d59a68595130fc75481c04980644e3e.png

服务端和客户端分别发送信息

0092ad90d74d613f795e31f51d00077f.png

服务端和客户端分别连续发送信息(可同时发送和接收信息)

7e1a0d0b41812bab39d35f99d5a2fe64.png

服务器和客户端分别发送长信息(最大为512个英文字符)

a695396b7591e0c2f060ef820a9aab84.png

27aeef3073720c92a9d211dc370e82ed.png

5.4 源代码

# socket
'''****server端****'''
'''/****20201124***/'''
from socket import *
import DES as des
import rsa
import threading
import time


print("当前时间:"+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

#key = '6A4B3C7D9E2F1F3F'
IV = [0x51, 0xA2, 0x6C, 0x32, 0x11, 0xF1, 0xD4, 0x09]
key = ''

# AF_INET --> IPv4  SOCK_STREAM --> TCP 

HOST = ''
PORT = 6666
BUFF = 1024
ADDR = (HOST,PORT)

s1 = socket(AF_INET,SOCK_STREAM)
s1.bind(ADDR)
s1.listen(5)
print('sever is running')
print('waiting for connection...')
conn, addr = s1.accept()
print('...connecting from:', addr)


def _SendMessage():
    while True:
        s1_send_data = input(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + ' 服务器>>>:')
        s1_send_data = des._DES(s1_send_data, key, IV, 0)
        s1_send_data = s1_send_data.encode('utf-8')
        if len(s1_send_data) > 0:
            conn.send(s1_send_data)

def _RecvMessage():
    while True:
        s1_recv_data = conn.recv(BUFF)
        if not s1_recv_data:
            break
        s1_recv_data = s1_recv_data.decode()
        print('加密信息:'+s1_recv_data)
        s1_recv_data = des._DES(s1_recv_data, key, IV, 1)
        if s1_recv_data == 'quit': 
            break
        print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + ' 客户端>>>:' + s1_recv_data)
        
class A(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
    
        def run(self):
            _RecvMessage()


while True:
    if not key:
        s1_recv_data = conn.recv(BUFF)
        
        if s1_recv_data.decode('utf-8') == 'changekey':
            print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' start to change key!')
            (pubkey, privkey) = rsa.newkeys(512, poolsize=8)
            print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' create pubkey & privkey')
            modulus = pubkey.n
            exponent = pubkey.e
            conn.send(str(modulus).encode('utf-8'))
            conn.send(str(exponent).encode('utf-8'))
            print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' send pubkey')
            key = conn.recv(BUFF)
            print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' recv encrypted des-key')
            key = rsa.decrypt(key, privkey)
            print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' decrypt des-key')
            key = key.decode()
    a = A()  
    a.start()
    _SendMessage()
        
#s1.close()
        
        
# socket
'''****client端****'''
'''/****20201124***/'''

from socket import *
import DES as des
import rsa
import threading
import time



print("当前时间:"+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

IV = [0x51, 0xA2, 0x6C, 0x32, 0x11, 0xF1, 0xD4, 0x09]

HOST = 'localhost'
PORT = 6666
BUFF =1024
ADDR = (HOST,PORT)

t = 2

s2 = socket(AF_INET,SOCK_STREAM)
s2.connect(ADDR)

key = '6A4B3C7D9E2F1F3F'

print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' start to change key!')
s2.send('changekey'.encode('utf-8'))

modulus = int(s2.recv(BUFF).decode('utf-8'))
exponent = int(s2.recv(BUFF).decode('utf-8'))

print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' start to build pubkey')
pubkey = rsa.PublicKey(modulus, exponent)

print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' encrypt des-key')
crypto = rsa.encrypt(key.encode('utf8'), pubkey)

print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' send encrypted des-key')
s2.send(crypto)

def _SendMessage():
    while True:
        s2_send_data = input(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + ' 客户端>>>:')
        s2_send_data = des._DES(s2_send_data, key, IV, 0)
        s2_send_data = s2_send_data.encode('utf-8')
        if len(s2_send_data) > 0:
            s2.send(s2_send_data)
            
def _RecvMessage():
    while True:
        time.sleep(t)
        s2_recv_data = s2.recv(BUFF)
    
        if not s2_recv_data:
            break
   
        s2_recv_data = s2_recv_data.decode()
        print('加密信息:'+s2_recv_data)
        s2_recv_data = des._DES(s2_recv_data, key, IV, 1)
    
        if s2_recv_data == 'quit':
            break 
        print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + ' 服务端>>>:' + s2_recv_data)
    
class A(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
    
        def run(self):
            _SendMessage()

a = A()
a.start()
    
while True:
    _RecvMessage()
       
#s2.close()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值