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.

271 lines
8.6 KiB

# 客户端(用户B)
import os
from tkinter import *
from tkinter.filedialog import askopenfilename
import socket
import threading
from Crypto import Signature
import rsa
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import base64
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.Hash import SHA
from rsa.pkcs1 import sign
import chardet
class b():
def t2():
client = socket.socket() # 生成socket连接对象
ip_port =("localhost", 6969) # 地址和端口号
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"))
#读取密钥
rsakey2 = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/kb/private.pem").read())
signer = Signature_pkcs1_v1_5.new(rsakey2)
digest = SHA.new()
if mode.get()=="rsa":
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/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/综合实验/kb/aeskey.pem", 'rb')
AESKEY=fk.read()
fk.close()
rsakey = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/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)
def t3():
server = socket.socket()
server.bind(("localhost", 6970)) # 绑定监听端口
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]="a2b"+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/综合实验/kb/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/综合实验/ka/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/综合实验/kb/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)
print(Signature)
rsakey2 = RSA.importKey(open("C:/Users/Shinelon/Desktop/综合实验/ka/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()
root = Tk()
path = StringVar()
state = StringVar()
mode1=StringVar()
result=StringVar()
path = StringVar()
state = StringVar()
mode=StringVar()
root.title("client")
def createkey(): #生成密钥
(pubkey, privkey) = rsa.newkeys(1024)
# 生成公钥
pub = pubkey.save_pkcs1()
pubfile = open("C:/Users/Shinelon/Desktop/综合实验/kb/public.pem", 'wb')
pubfile.write(pub)
pubfile.close()
# 生成私钥
pri = privkey.save_pkcs1()
prifile = open("C:/Users/Shinelon/Desktop/综合实验/kb/private.pem", 'wb')
prifile.write(pri)
prifile.close()
def selectPath(): #获取文件路径
path_ = askopenfilename()
path.set(path_)
print(path_)
def add_to_16(par):
# par = par.encode() #先将字符串类型数据转换成字节型数据
while len(par) % 16 != 0: #对字节型数据进行长度判断
par += b'\x00' #如果字节型数据长度不是16倍整数就进行 补充
return par
def t1():
mode.set(m.get())
t2=threading.Thread(target=b.t2)
t2.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=t1).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)
t3=threading.Thread(target=t3)
t3.start()
root.mainloop()