安全协议的实验,使用python的serversocket库实现了客户端与客户端的全双工通信,同时使用了RSA加密与签名,随机挑战等加密方式。代码还有些bug,bug再RSA的加解密部分,传输内容过长时会报错😓。暂时没写注释😀。代码Linux与Windows通用。
目录结构
代码部分
MyClient
--------EncryptRsa.py
import rsa
(pubkey, privkey) = rsa.newkeys(512)
def rsaEncrypt(str,pubkey):
# 明文编码格式
content = str.encode("utf-8")
# 公钥加密
crypto = rsa.encrypt(content, pubkey)
return crypto
# rsa解密
def rsaDecrypt(str, privkey):
# 私钥解密
content = rsa.decrypt(str, privkey)
con = content.decode("utf-8")
return con
def rsaEncryptByte(bt,pubkey):
# 公钥加密
crypto = rsa.encrypt(bt, pubkey)
return crypto
def rsaDecryptByte(bt, privkey):
# 私钥解密
content = rsa.decrypt(str, privkey)
con = content.decode("utf-8")
return con
def rsaSign(str,privkey):
return rsa.sign(str.encode(),privkey,"SHA-256")
def rsaVerify(str,singStr,pubkey):
return rsa.verify(str.encode(),singStr,pubkey) #返回加密方式
MyClient
--------Sclient.py
import socket # 导入 socket 模块
import json
import struct
import pickle
import threading
import EncryptRsa
import hashlib
import sys
secKey = input("input Secret Key: ")
class SocketClient:
def __init__(self):
self.start()
def start(self):
self.con = socket.socket() # 创建 socket 对象
host = "127.0.0.1" # 获取本地主机名
port = 8887 # 设置端口号
if len(sys.argv) < 2:
print("将使用默认参数")
else:
host = sys.argv[1]
port = sys.argv[2]
print("connect host "+host)
print("connect port "+port)
self.con.connect((host, int(port)))
self.exchangeKey()
try:
th = threading.Thread(target=self.serverLisent,args=())
th.start()
while True:
self.sendMsg(input(),self.privkey)
finally:
self.con.close()
exit(0)
def serverLisent(self):
while True:
try:
print("来自服务器: " + self.recvMsg(self.serverPubKey))
except:
exit(0)
def recvMsg(self,pubkey):
header_len = self.con.recv(4)
header_len_unpack = struct.unpack("i", header_len)[0]
header_bytes = self.con.recv(header_len_unpack)
header = json.loads(header_bytes.decode("utf-8"))
msg = self.con.recv(header["Textlen"])
msgMd5Sign = self.recvMsgBytes()
data = EncryptRsa.rsaDecrypt(msg,self.privkey)
msgMd5 = header["sumMd5"]
clacMd5 = hashlib.md5(data.encode("utf-8")).hexdigest()
if (msgMd5 != clacMd5):
print("消息被篡改")
return 0
try:
verifyMd5 = EncryptRsa.rsaVerify(msgMd5, msgMd5Sign, pubkey)
if (verifyMd5 == "SHA-256"):
return data
else:
print("中间人介入")
return 0
except:
print("中间人介入")
return 0
def sendMsg(self,msg,privKey):
msgEncrpt = EncryptRsa.rsaEncrypt(msg,self.serverPubKey)
msgMd5 = hashlib.md5(msg.encode("utf-8")).hexdigest()
header = {"Textlen":len(msgEncrpt),"sumMd5":msgMd5}
header_bytes = bytes(json.dumps(header),encoding="utf-8")
header_len_bytes = struct.pack("i",len(header_bytes))
self.con.send(header_len_bytes)
self.con.send(header_bytes)
self.con.send(msgEncrpt)
self.sendMsgBytes(EncryptRsa.rsaSign(msgMd5,privKey))
def sendMsgBytes(self,msg):
header = {"Textlen":len(msg)}
header_bytes = bytes(json.dumps(header),encoding="utf-8")
header_len_bytes = struct.pack("i",len(header_bytes))
self.con.send(header_len_bytes)
self.con.send(header_bytes)
self.con.send(msg)
def recvMsgBytes(self):
header_len = self.con.recv(4)
header_len_unpack = struct.unpack("i", header_len)[0]
header_bytes = self.con.recv(header_len_unpack)
header = json.loads(header_bytes.decode("utf-8"))
data = self.con.recv(header["Textlen"])
return data
def exchangeKey(self):
self.pubkey = EncryptRsa.pubkey
self.privkey = EncryptRsa.privkey
pubkeySeri = pickle.dumps(self.pubkey)
self.sendMsgBytes(pubkeySeri)
self.serverPubKey = (pickle.loads(self.recvMsgBytes()))
print("server punkey is ")
print(self.serverPubKey)
challenge = self.recvMsg(self.serverPubKey).encode("utf-8")
challengeMD5_SEND = hashlib.md5(challenge + secKey.encode("utf-8")).hexdigest()
self.sendMsg(challengeMD5_SEND,self.privkey)
def __del__(self):
self.con.close() # 关闭连接
a = SocketClient()
while True:
pass
MyServer
--------EncryptRsa.py
import rsa
(pubkey, privkey) = rsa.newkeys(512)
def rsaEncrypt(str,pubkey):
# 明文编码格式
content = str.encode("utf-8")
# 公钥加密
crypto = rsa.encrypt(content, pubkey)
return crypto
# rsa解密
def rsaDecrypt(str, privkey):
# 私钥解密
content = rsa.decrypt(str, privkey)
con = content.decode("utf-8")
return con
def rsaEncryptByte(bt,pubkey):
# 公钥加密
crypto = rsa.encrypt(bt, pubkey)
return crypto
def rsaDecryptByte(bt, privkey):
# 私钥解密
content = rsa.decrypt(str, privkey)
con = content.decode("utf-8")
return con
def rsaSign(str,privkey):
return rsa.sign(str.encode(),privkey,"SHA-256")
def rsaVerify(str,singStr,pubkey):
return rsa.verify(str.encode(),singStr,pubkey) #返回加密方式
MyServer
--------Sserver.py
import socketserver
import struct
import json
import pickle
import EncryptRsa
import hashlib
import random
import sys
clientList = []
secKey = "123"
globalPubkey = EncryptRsa.pubkey
globalprivkey = EncryptRsa.privkey
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
clientList.append(self)
self.listIndex = len(clientList) - 1
print("seq is " + str(self.listIndex))
print(clientList[self.listIndex].client_address[0] + "已连接")
self.exchangeKey()
self.msgLisent()
def msgLisent(self):
sendMsg(self.request, "连接服务器成功", self.cilentPubKey,self.privkey)
while True:
msg = recvMsg(self.request,self.privkey,self.cilentPubKey)
print("来自客户端"+ self.client_address[0] + ": " + msg)
for con in clientList:
sendMsg(con.request, "from " + self.client_address[0]+ " :" +msg, con.cilentPubKey,self.privkey)
print("已发送 '{}' 至 ".format(msg) + con.client_address[0])
def finish(self):
self.request.close()
print(self.client_address[0] + " already exit")
del clientList[self.listIndex]
del self
def exchangeKey(self):
self.cilentPubKey = (pickle.loads(recvMsgBytes(self.request)))
self.pubkey = globalPubkey
self.privkey = globalprivkey
pubkeySeri = pickle.dumps(self.pubkey)
sendMsgBytes(self.request,pubkeySeri)
print("clent {} pubkey is ".format(self.client_address[0]))
print(self.cilentPubKey)
challenge = str(random.random()).encode("utf-8")
chasecr = challenge + secKey.encode("utf-8")
sendMsg(self.request,challenge.decode("utf-8"),self.cilentPubKey,self.privkey)
challengeMd5_Recv = recvMsg(self.request,self.privkey,self.cilentPubKey)
challengeMD5_Orin = hashlib.md5(chasecr).hexdigest()
if(challengeMd5_Recv == challengeMD5_Orin):
print(self.client_address[0] + "随机挑战成功")
else:
sendMsg(self.request, "secret key error", self.cilentPubKey,self.privkey)
self.request.close()
del clientList[self.listIndex]
def sendMsg(conn, msg,pubkey,privKey):
msgEncypt = EncryptRsa.rsaEncrypt(msg,pubkey)
msgMd5 = hashlib.md5(msg.encode("utf-8")).hexdigest()
header = {"Textlen": len(msgEncypt),"sumMd5":msgMd5}
header_bytes = bytes(json.dumps(header), encoding="utf-8")
header_len_bytes = struct.pack("i", len(header_bytes))
conn.send(header_len_bytes)
conn.send(header_bytes)
conn.send(msgEncypt)
sendMsgBytes(conn,EncryptRsa.rsaSign(msgMd5,privKey))
def recvMsg(conn,privkey,pubkey):
header_len = conn.recv(4)
header_len_unpack = struct.unpack("i", header_len)[0]
header_bytes = conn.recv(header_len_unpack)
header = json.loads(header_bytes.decode("utf-8"))
msg = conn.recv(header["Textlen"])
Md5Sign = recvMsgBytes(conn)
msgMd5 = header["sumMd5"]
data = EncryptRsa.rsaDecrypt(msg,privkey)
clacMd5 = hashlib.md5(data.encode("utf-8")).hexdigest()
if (msgMd5 != clacMd5):
print("消息被篡改")
return 0
try:
verifyMd5 = EncryptRsa.rsaVerify(msgMd5,Md5Sign,pubkey)
if(verifyMd5 == "SHA-256"):
return data
else:
print("中间人介入")
return 0
except:
print("中间人介入")
return 0
def recvMsgBytes(conn):
header_len = conn.recv(4)
header_len_unpack = struct.unpack("i", header_len)[0]
header_bytes = conn.recv(header_len_unpack)
header = json.loads(header_bytes.decode("utf-8"))
data = conn.recv(header["Textlen"])
return data
def sendMsgBytes(conn,msg):
header = {"Textlen":len(msg)}
header_bytes = bytes(json.dumps(header),encoding="utf-8")
header_len_bytes = struct.pack("i",len(header_bytes))
conn.send(header_len_bytes)
conn.send(header_bytes)
conn.send(msg)
def start():
host = "127.0.0.1"
port = 8887 # 设置端口
if(len(sys.argv) < 2):
print("将使用默认参数")
else:
host = sys.argv[1]
port = sys.argv[2]
print("lisent host "+host)
print("lisent port "+port)
server = socketserver.ThreadingTCPServer((host, int(port)), MyTCPHandler)
server.serve_forever()
if __name__ == "__main__":
start()