You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
8.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 服务端用户A
from os import SEEK_SET
from tkinter import *
from tkinter.filedialog import askopenfilename
import socket
import threading
import rsa
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import base64
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.Hash import SHA
from binascii import b2a_hex, a2b_hex
import chardet
class a():
def t3():
client = socket.socket() # 生成socket连接对象
ip_port =("localhost", 6970) # 地址和端口号
client.connect(ip_port) # 连接
print("服务器已连接")
sn=len(path.get().encode("utf-8"))
client.send(str(sn).encode("utf-8"))
# size=os.stat(path.get()).st_size
client.send(path.get().encode("utf-8")) #文件名
client.send(mode.get().encode("utf-8"))
# client.send(str(size).encode("utf-8")) #大小
#读取密钥
rsakey2 = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/private.pem").read())
signer = Signature_pkcs1_v1_5.new(rsakey2)
digest = SHA.new()
if mode.get()=="rsa":
# fpk=open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem", 'rb')
# pk=fpk.read()
# fpk.close()
# fpr=open("C:/Users/Shinelon/Desktop/综合实验/kb/private.pem", 'rb')
# pr=fpr.read()
# fpr.close
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem").read())
cipher = Cipher_pkcs1_v1_5.new(rsakey) #创建用于执行pkcs1_v1_5加密或解密的密码
# cipher_text = base64.b64encode(cipher.encrypt(message.encode('utf-8')))
f=open(path.get(),"rb")
for line in f:
# print(pr.decode("utf-8"))
digest.update(line)
crypto=base64.b64encode(cipher.encrypt(line))
size=len(crypto)
client.send(str(size).encode("utf-8"))
client.send(crypto)
f.close()
sign=signer.sign(digest)
Signature=base64.b64encode(sign)
client.send(' '.encode("utf-8")) #停止接收文件,开始接收摘要
# client.send(str(len(Signature)).encode("utf-8"))
client.send(str(len(Signature)).encode("utf-8"))
client.send(Signature)
#AES
elif mode.get()=="aes":
fk=open("C:/Users/Shinelon/Desktop/综合实验/ka/aeskey.pem", 'rb')
AESKEY=fk.read()
fk.close()
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem").read())
cipher = Cipher_pkcs1_v1_5.new(rsakey)
crypto=base64.b64encode(cipher.encrypt(AESKEY))
client.send(str(len(crypto)).encode("utf-8"))
client.send(crypto)
model = AES.MODE_ECB
aes = AES.new(add_to_16(AESKEY),model)
f=open(path.get(),"rb")
for line in f:
# print(pr.decode("utf-8"))
digest.update(line)
crypto=add_to_16(line)
crypto=aes.encrypt(crypto)
crypto=base64.encodebytes(crypto).decode().strip()
size=len(crypto)
s=len(str(size))
client.send(str(s).encode("utf-8"))
client.send(str(size).encode("utf-8"))
client.send(crypto.encode("utf-8"))
f.close()
sign=signer.sign(digest)
Signature=base64.b64encode(sign)
client.send(' '.encode("utf-8")) #停止接收文件,开始接收摘要
# client.send(str(len(Signature)).encode("utf-8"))
client.send(str(len(Signature)).encode("utf-8"))
client.send(Signature)
root = Tk()
path = StringVar()
mode1=StringVar()
result=StringVar()
mode=StringVar()
root.title("server")
def selectPath():
path_ = askopenfilename()
path.set(path_)
def createkey():
(pubkey, privkey) = rsa.newkeys(1024)
# 生成公钥
pub = pubkey.save_pkcs1()
pubfile = open("C:/Users/Shinelon/Desktop/综合实验/ka/public.pem", 'wb')
pubfile.write(pub)
pubfile.close()
# 生成私钥
pri = privkey.save_pkcs1()
prifile = open("C:/Users/Shinelon/Desktop/综合实验/ka/private.pem", 'wb')
prifile.write(pri)
prifile.close()
def t2():
server = socket.socket()
server.bind(("localhost", 6969)) # 绑定监听端口
server.listen(5) # 监听
print("监听开始..")
while True:
conn, addr = server.accept() # 等待连接
print("conn:", conn, "\naddr:", addr) # conn连接实例
# while True:
sn=conn.recv(2)
fname=conn.recv(int(sn))
filename=fname.decode("utf-8")
fl=filename.split("/")
fl[5]="b2a"+fl[5]
filename="/".join(fl)
mode=conn.recv(3)
mode=mode.decode("utf-8")
mode1.set(mode)
if mode=="rsa":
f=open(filename,"wb")
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/private.pem").read())
cipher = Cipher_pkcs1_v1_5.new(rsakey)
# received_size=0
while True:
size=conn.recv(3)
size=size.decode("utf-8")
if size!=' ':
size=int(size)
data=conn.recv(size)
data=cipher.decrypt(base64.b64decode(data), "解密失败")
f.write(data)
else:
break
f.close()
sl=conn.recv(3)
Signature=conn.recv(int(sl.decode("utf-8")))
rsakey2 = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem").read())
verifier = Signature_pkcs1_v1_5.new(rsakey2)
hsmsg = SHA.new()
f=open(filename,"rb")
for line in f:
hsmsg.update(line)
f.close()
is_verify = verifier.verify(hsmsg, base64.b64decode(Signature.decode("utf-8")))
if is_verify:
result.set("文件未被篡改")
else:
result.set("文件可能被篡改")
elif mode=="aes":
#获取密钥
kl=conn.recv(3)
kl=int(kl.decode("utf-8"))
key=conn.recv(kl)
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/private.pem").read())
cipher = Cipher_pkcs1_v1_5.new(rsakey)
AESKEY=cipher.decrypt(base64.b64decode(key), "解密失败")
model = AES.MODE_ECB
aes = AES.new(add_to_16(AESKEY),model)
f=open(filename,"wb")
while True:
s=conn.recv(1)
s=s.decode("utf-8")
if s!=' ':
s=int(s)
size=conn.recv(s)
size=size.decode("utf-8")
size=int(size)
data=conn.recv(size)
data=base64.decodebytes(data)
data=str(aes.decrypt(add_to_16(data)),encoding="GBK").strip('\0')
f.write(data.encode("GBK"))
else:
break
f.close()
sl=conn.recv(3)
Signature=conn.recv(int(sl.decode("utf-8")))
# Signature=conn.recv(172)
rsakey2 = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem").read())
verifier = Signature_pkcs1_v1_5.new(rsakey2)
hsmsg = SHA.new()
f=open(filename,"rb")
for line in f:
hsmsg.update(line)
f.close()
is_verify = verifier.verify(hsmsg, base64.b64decode(Signature.decode("utf-8")))
if is_verify:
result.set("文件未被篡改")
else:
result.set("文件可能被篡改")
if 1==2:
break
server.close()
def add_to_16(par):
# par = par.encode() #先将字符串类型数据转换成字节型数据
while len(par) % 16 != 0: #对字节型数据进行长度判断
par += b'\x00' #如果字节型数据长度不是16倍整数就进行 补充
return par
def tt():
mode.set(m.get())
t3=threading.Thread(target=a.t3)
t3.start()
Label(root,text = "发送:").grid(row = 0, column = 0)
Entry(root, textvariable = path).grid(row = 1, column = 1)
Button(root, text = "路径选择", command = selectPath).grid(row = 1, column = 0)
Label(root,text = "加密模式:").grid(row = 2, column = 0)
m=Entry(root, textvariable = mode)
m.grid(row = 2, column = 1)
Button(root,text="生成密钥",command=createkey).grid(row=3,column=0)
Button(root,text="发送" ,command=tt).grid(row=3,column=1)
Label(root,text = "接收:").grid(row = 4, column = 0)
Label(root,text = "加密模式:").grid(row = 5, column = 0)
Entry(root, textvariable = mode1).grid(row = 5, column = 1)
Label(root,text = "验证结果:").grid(row = 6, column = 0)
Entry(root, textvariable = result).grid(row = 6, column = 1)
t2=threading.Thread(target=t2)
t2.start()
root.mainloop()