├── .gitignore
├── .idea
├── .gitignore
├── .name
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── networksec.iml
└── vcs.xml
├── Client.py
├── README.md
├── Server.py
├── algorithms
├── AESalgorithm.py
├── RSAalgorithm.py
├── __pycache__
│ ├── AESalgorithm.cpython-38.pyc
│ └── RSAalgorithm.cpython-38.pyc
├── generateKey.py
└── hashalg.py
├── img.assets
├── clip_image002.png
├── clip_image004.png
├── clip_image006.jpg
├── clip_image008.jpg
├── clip_image010.jpg
├── clip_image012.jpg
├── clip_image014.jpg
├── clip_image016.jpg
├── clip_image018.jpg
├── clip_image020.jpg
├── clip_image022.jpg
├── clip_image024.jpg
├── clip_image026.jpg
├── clip_image028.jpg
├── clip_image030.jpg
└── clip_image032.jpg
├── keys
├── client
│ ├── clientprivate.pem
│ └── clientpublic.pem
└── server
│ ├── serverprivate.pem
│ └── serverpublic.pem
└── test
├── client.py
├── tclient.py
└── tserver.py
/.gitignore:
--------------------------------------------------------------------------------
1 | /venv/
2 | /venv1/
3 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | windowsGui.py
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/networksec.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Client.py:
--------------------------------------------------------------------------------
1 | import struct
2 | from tkinter import *
3 | import time
4 | from tkinter import filedialog
5 | import pickle
6 | import socket
7 | import threading
8 | import tkinter.messagebox
9 | from algorithms import AESalgorithm, generateKey, RSAalgorithm, hashalg
10 | from tkinter import ttk
11 | import json
12 | import os
13 | import base64
14 |
15 | # 使用tkinter建立GUI
16 |
17 | IP = '127.0.0.1'
18 | PORT = 4396
19 | BUFF = 5120
20 | FIP='127.0.0.1'
21 | FPORT=7932
22 |
23 | # SERVERPUBLIC
24 | # CLIENTPUBLIC
25 | # CLIENTPRIVATE
26 | def initKey():
27 | global CLIENTPUBLIC, CLIENTPRIVATE
28 | (CLIENTPRIVATE, CLIENTPUBLIC) = generateKey.generateMyKey("keys/client/client")
29 |
30 | def fileEncrypt(data):
31 | onceKey = AESalgorithm.genKey()
32 | print("发送的密钥",onceKey)
33 | digest = RSAalgorithm.RsaSignal(data, CLIENTPRIVATE)
34 | message = {'Message': base64.b64encode(data), 'digest': digest.decode("utf-8")} # 把消息和摘要打包
35 | message = pickle.dumps(message) # 转成json字符串
36 | message = AESalgorithm.AesEncrypt(message, onceKey)
37 | encrykey = RSAalgorithm.RsaEncrypt(onceKey, SERVERPUBLIC)
38 | MES = pickle.dumps([message, encrykey.decode('utf-8')])
39 | return MES
40 |
41 |
42 |
43 |
44 |
45 | def initSendSocket(filepath):
46 | try:
47 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
48 | s.connect((FIP, FPORT))
49 | except socket.error as msg:
50 | print(msg)
51 | sys.exit(1)
52 | print(s.recv(10240))
53 |
54 | # 需要传输的文件路径
55 |
56 | # 判断是否为文件
57 | if os.path.isfile(filepath):
58 | # 定义定义文件信息。128s表示文件名为128bytes长,l表示一个int或log文件类型,在此为文件大小
59 | fileinfo_size = struct.calcsize('128sl')
60 | # 定义文件头信息,包含文件名和文件大小
61 | fhead = struct.pack('128sl', os.path.basename(filepath).encode('utf-8'), os.stat(filepath).st_size)
62 | # 发送文件名称与文件大小
63 | s.send(fhead)
64 |
65 | # 将传输文件以二进制的形式分多次上传至服务器
66 | fp = open(filepath, 'rb')
67 | while True:
68 | global rere
69 | rere=''
70 | data = fp.read(1024)
71 | if not data:
72 | print('{0} 文件发送完毕...'.format(os.path.basename(filepath)))
73 | txtMsgList.insert(END, '{0} 文件发送完毕...'.format(os.path.basename(filepath)), 'greencolor')
74 | break
75 | print("发送的内容",data)
76 | tosend=fileEncrypt(data)
77 | s.send(str(len(tosend)).encode('utf-8'))
78 | s.send(tosend)
79 | while True:
80 | if s.recv(1024).decode('utf-8')=='I have receive the past one':
81 | break
82 |
83 |
84 | # 关闭当期的套接字对象
85 | s.close()
86 |
87 |
88 |
89 | # 主页
90 | def mainPage():
91 | def sendMsg(Sock): # 发送消息
92 | strMsg = "我:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n'
93 | txtMsgList.insert(END, strMsg, 'greencolor')
94 | Mes = txtMsg.get('0.0', END)
95 | txtMsgList.insert(END, Mes)
96 | onceKey = AESalgorithm.genKey() # 一次一密 密钥
97 | digest = RSAalgorithm.RsaSignal(Mes, CLIENTPRIVATE) # 先hash再签名# 生成消息摘要
98 | message = {'Message': Mes, 'digest': digest.decode("utf-8")} # 把消息和摘要打包
99 | message = json.dumps(message) # 转成json字符串
100 | message = AESalgorithm.AesEncrypt(message, onceKey) # 合并加密
101 | encrykey = RSAalgorithm.RsaEncrypt(onceKey, SERVERPUBLIC) # 用服务器公钥加密一次密钥
102 | txtMsg.delete('0.0', END)
103 | Message = pickle.dumps([message, encrykey.decode('utf-8')]) # 序列化消息,用于传输
104 | Sock.send(Message)
105 |
106 | def RecvMsg(Sock, test): # 接受消息函数
107 | global SERVERPUBLICs
108 | while True:
109 | Message = Sock.recv(BUFF) # 收到文件
110 | (message, encrykey) = pickle.loads(Message)
111 |
112 | mykey = RSAalgorithm.RsaDecrypt(encrykey, CLIENTPRIVATE) # 用私钥解密获得一次密钥
113 | print('mykey', mykey.decode('utf-8'))
114 | decryMes = AESalgorithm.AesDecrypt(message, mykey.decode('utf-8')) # 用一次密钥解密消息,获得包含消息内容和摘要的json
115 | decryMes = json.loads(decryMes) # 将json转换为python字典
116 | content = decryMes['Message']
117 | digest = decryMes['digest'].encode('utf-8')
118 |
119 | if RSAalgorithm.VerRsaSignal(content, digest, SERVERPUBLIC):
120 | strMsg = "对方:" + time.strftime("%Y-%m-%d %H:%M:%S",
121 | time.localtime()) + "通过数字签名认证,本次密钥为" + mykey.decode('utf-8') + '\n'
122 | txtMsgList.insert(END, strMsg, 'greencolor')
123 | txtMsgList.insert(END, content + '\n')
124 |
125 | def cancelMsg(): # 清空消息内容
126 | txtMsg.delete('0.0', END)
127 |
128 | def sendMsgEvent(event, Sock): # 发送消息事件
129 | if event.keysym == 'Up':
130 | sendMsg(Sock)
131 |
132 | def UploadAction(event=None): # 上传文件
133 | filename = filedialog.askopenfilename()
134 | print('Selected:', filename)
135 | initSendSocket(filename)
136 |
137 | def exchangePublicKey(dir):
138 | global ClientSock, txtMsgList
139 | with open(dir, 'rb') as fi:
140 | publicKey = fi.read()
141 | has = hashalg.hash_sha256(publicKey)
142 | Message = pickle.dumps([publicKey, has])
143 | try:
144 | ClientSock.send(Message)
145 | txtMsgList.insert(END, "发送公钥成功\n")
146 | except:
147 | txtMsgList.insert(END, "密钥发送失败,正在尝试重新发送...\n")
148 | exchangePublicKey(dir)
149 |
150 | def verifyKey(Sock):
151 | global txtMsgList, SERVERPUBLIC
152 | while True:
153 | Message = Sock.recv(BUFF)
154 | (publickey, hash_256) = pickle.loads(Message)
155 | if hash_256 == hashalg.hash_sha256(publickey):
156 | txtMsgList.insert(END, "公钥完整性验证完成,可以开始传输文件\n")
157 | SERVERPUBLIC = publickey
158 | txtMsgList.insert(END, "收到公钥\n" + SERVERPUBLIC.decode('utf-8') + "\n")
159 |
160 | break
161 | else:
162 | txtMsgList.insert(END, "验证失败\n")
163 |
164 | def cnct(): # 连接操作
165 | global txtMsgList, ClientSock
166 | ClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
167 | ServerAddr = IP
168 | ClientSock.connect((ServerAddr, PORT))
169 | print('连接成功,可以开始传输消息和文件了\n')
170 | txtMsgList.insert(END, "连接成功,可以开始传输消息和文件了" + IP + ":" + str(PORT) + "\n")
171 | exchangePublicKey("keys/client/clientpublic.pem") # 发送公钥
172 | verifyKey(ClientSock) # 验证对方密钥
173 | thread = threading.Thread(target=RecvMsg, args=(ClientSock, None))
174 | thread.start()
175 | return ClientSock
176 |
177 | def setIpWindows(): # 设置ip的子窗口
178 | def setNewIP(newip, newport):
179 | global txtMsgList
180 | print(newip, newport)
181 | global IP
182 | IP = str(newip)
183 | global PORT
184 | PORT = int(newport)
185 | set.destroy()
186 | try:
187 | cnct()
188 | except:
189 | txtMsgList.insert(END, "连接异常,ip或端口不可访问")
190 | tkinter.messagebox.showwarning('连接失败', '连接异常,ip或端口不可访问\n')
191 | print("连接异常,ip或端口不可访问\n")
192 |
193 | set = Tk()
194 | set.title('设置ip地址和端口号')
195 | set.geometry('350x200')
196 | set.resizable(0, 0)
197 | # ip
198 | Label(set, text='IP地址:').place(x=10, y=10)
199 | ent1 = Entry(set)
200 | ent1.place(x=150, y=10)
201 | # port
202 | Label(set, text='端口号:').place(x=10, y=50)
203 | ent2 = Entry(set)
204 | ent2.place(x=150, y=50)
205 | bt_connect = Button(set, text='连接', command=lambda: setNewIP(ent1.get(), ent2.get()))
206 | bt_connect.place(x=150, y=130)
207 | set.mainloop()
208 |
209 | def start():
210 | # 以下是生成聊天窗口的代码
211 | def selectEven(*args):
212 | print(selal.get())
213 |
214 | global app, frmLT, frmLC, frmLB, txtMsgList, txtMsg, btnSend, btnCancel, btnFile, btnSet
215 | # 创建窗口
216 | app = Tk()
217 | app.title('网络加密软件-Client')
218 | app.resizable(0, 0)
219 |
220 | # 创建frame容器
221 | frmLT = Frame(width=500, height=320, bg='white')
222 | frmLC = Frame(width=500, height=150, bg='white')
223 | frmLB = Frame(width=500, height=30)
224 | # frmRT = Frame(width = 200, height = 500)
225 |
226 | # 创建控件
227 | txtMsgList = Text(frmLT)
228 | txtMsgList.tag_config('greencolor', foreground='#008C00') # 创建tag
229 | txtMsg = Text(frmLC)
230 | txtMsg.bind("", sendMsgEvent)
231 | selal = StringVar()
232 | btnSend = Button(frmLB, text='发送', width=8, command=lambda: sendMsg(ClientSocket))
233 | btnCancel = Button(frmLB, text='取消', width=8, command=cancelMsg)
234 | btnFile = Button(frmLB, text='上次文件', width=8, command=UploadAction)
235 | btnSet = Button(frmLB, text='设置ip', width=8, command=setIpWindows)
236 | btnAlSel = ttk.Combobox(frmLB, textvariable=selal, state='readonly')
237 | btnAlSel['values'] = ('AES-CBC-一次一密', '待定2')
238 | btnAlSel.current(0)
239 | btnAlSel.bind("<>", selectEven)
240 | print("selal is ", selal.get())
241 | # btnFile.pack()
242 | # imgInfo = PhotoImage(file = "timg-2.gif")
243 | # lblImage = Label(frmRT, image = imgInfo)
244 | # lblImage.image = imgInfo
245 |
246 | # 窗口布局
247 | frmLT.grid(row=0, column=0, columnspan=2, padx=1, pady=3)
248 | frmLC.grid(row=1, column=0, columnspan=2, padx=1, pady=3)
249 | frmLB.grid(row=2, column=0, columnspan=2)
250 | # frmRT.grid(row = 0, column = 2, rowspan = 3, padx =2, pady = 3)
251 |
252 | # 固定大小
253 | frmLT.grid_propagate(0)
254 | frmLC.grid_propagate(0)
255 | frmLB.grid_propagate(0)
256 | # frmRT.grid_propagate(0)
257 |
258 | btnSend.grid(row=2, column=0)
259 | btnCancel.grid(row=2, column=1)
260 | btnFile.grid(row=2, column=2)
261 | btnSet.grid(row=2, column=3)
262 | btnAlSel.grid(row=2, column=4)
263 | # lblImage.grid()
264 | txtMsgList.grid()
265 | txtMsg.grid()
266 | # 主事件循环
267 | app.mainloop()
268 |
269 | thread_gui = threading.Thread(target=start)
270 | thread_gui.start()
271 |
272 | ClientSocket = cnct()
273 | # try:
274 | # ClientSocket=cnct()
275 | # except:
276 | # addSysTip("连接异常,ip或端口不可访问")
277 | # tkinter.messagebox.showwarning('连接失败', '连接异常,ip或端口不可访问,点击设置按钮重新设置\n')
278 | # print("连接异常,ip或端口不可访问\n")
279 |
280 |
281 | def main():
282 | initKey()
283 | mainPage()
284 |
285 |
286 | if __name__ == "__main__":
287 | main()
288 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 本项目为本科课程设计项目,时间比较久远,已经停止维护,一些异常是由于包版本或者python版本兼容性的问题导致的(例如一些三方加密包)。由于个人没有多余的精力重新维护该项目,故无法提供支持,望理解。如有对本项目感兴趣的小伙伴欢迎修复并提交合并。有维护意向的小伙伴欢迎与我联系。
2 |
3 | ## 1 设计思路
4 |
5 | 在本安全通讯系统中,我采用了先签名后加密的设计思路,并且结合了电子信封将对称密钥通过非对称加密,实现密钥安全传输的一次一密加密系统。提供了保密性、消息认证和数字签名。在系统连接之初,双方生成公钥私钥后,进行公钥交换,通过SHA256算法生成数字摘要,提供完整性校验。本系统单钥加密算法采用CBC模式的AES算法,用于对消息和签名一起进行加密和解密。非对称加密算法采用RSA,用于签名和验证签名,加密密钥和解密密钥。系统采用CS模式的TCP连接,消息系统和文件传输系统采用独立线程,同时GUI也单独运行在一个线程中。消息系统和文件系统采用相同的加密算法,实现上略有不同,消息系统建立的是长连接。文件系统传送文件时建立连接,传送完成即断开连接。编程语言采用Python。
6 |
7 | ### 1.2 发送方加密过程
8 |
9 | 
10 |
11 | ### 1.3 接收方解密过程
12 |
13 | 
14 |
15 | ### 1.4 软件界面
16 |
17 |
18 |
19 | 
20 |
21 | 
22 |
23 |
24 |
25 |
26 |
27 | ## 2 核心算法
28 |
29 | ### 2.1 RSA算法
30 |
31 | RSA算法使用发送方的私钥进行签名,使用对方公钥对单次密钥进行加密。接收方使用公钥解密单次密钥并通过发送方公钥验证签名。
32 |
33 | 
34 |
35 | 
36 |
37 | 
38 |
39 | 
40 |
41 | ### 2.2 CBC模式的AES算法
42 |
43 | CBC模式(密码分组链接),该模式的特点是使得每个分组加密依赖于所有以前的分组。AES算法采用的密钥长度和分组长度都是128位,如果分组长度不满足128位要进行填充。
44 |
45 | 
46 |
47 | 
48 |
49 | ### 2.3 加密过程(以传送消息为例,文件传输类似,实现略有不同)
50 |
51 | 
52 |
53 | ### 2.4 解密过程
54 |
55 | 
56 |
57 | ### 2.5 文件传输的加解密
58 |
59 | 文件传输采用的加解密过程和消息传输一样,采用先签名后加密的思想,并且签名前先生成消息摘要。密钥通过对方公钥进行加密,一并传输。消息传输和文件传输最大的区别是,文件大小不确定,每次发送的文件大小可能不一样,格式多样。并且因为socket缓冲区大小有限,为了实现大文件传输,必须要将大文件拆分,分段传输。每一次从文件中读取固定长度,然后对该部分内容加密后发送,由于每一段密文长度可能不同(最后一段和前面段),那么在传送每一段前先发送一个该段加密后的长度,便于接收方设置接受缓存。同时,为了解决文件格式以及方便接收方对文件完整性检验,需要在建立传输连接时,将文件名、格式、大小等信息传送给接收方。对每一段加密和解密的过程同消息传输。以下是部分核心代码。
60 |
61 | 
62 |
63 | 
64 |
65 |
66 |
--------------------------------------------------------------------------------
/Server.py:
--------------------------------------------------------------------------------
1 | import base64
2 | import struct
3 | from tkinter import *
4 | import time
5 | from tkinter import filedialog
6 | import pickle
7 | import socket
8 | import threading
9 | import tkinter.messagebox
10 | from algorithms import AESalgorithm, generateKey, RSAalgorithm, hashalg
11 | import json
12 |
13 | # 使用tkinter建立GUI
14 |
15 | IP = '127.0.0.1'
16 | PORT = 4396
17 | BUFF = 5120
18 | FIP='127.0.0.1'
19 | FPORT=7932
20 |
21 |
22 | # CLIENTPUBLICs
23 | # SERVERPUBLICs
24 | # SERVERPRIVATEs
25 | def initKey():
26 | global SERVERPUBLICs, SERVERPRIVATEs
27 | (SERVERPRIVATEs, SERVERPUBLICs) = generateKey.generateMyKey("keys/server/server")
28 |
29 | def fileDecrypt(data):
30 | (message,encrykey)=pickle.loads(data)
31 | onceKey= RSAalgorithm.RsaDecrypt(encrykey, SERVERPRIVATEs)
32 | print("接收到的密钥",onceKey,type(onceKey))
33 | message= AESalgorithm.AesDecrypt(message, onceKey.decode('unicode_escape'))
34 | message=pickle.loads(message)
35 | content=base64.b64decode(message['Message'])
36 | print('传送的内容是',content)
37 | digest=message['digest']
38 | if RSAalgorithm.VerRsaSignal(content, digest, CLIENTPUBLICs):
39 | return content
40 |
41 | def initFileListen():
42 | try:
43 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
45 | # 绑定端口为9001
46 | s.bind((FIP, FPORT))
47 | # 设置监听数
48 | s.listen(10)
49 | except socket.error as msg:
50 | print(msg)
51 | sys.exit(1)
52 | print('Waiting connection...')
53 |
54 | while True:
55 | # 等待请求并接受(程序会停留在这一旦收到连接请求即开启接受数据的线程)
56 | conn, addr = s.accept()
57 | # 接收数据
58 | t = threading.Thread(target=deal_data, args=(conn, addr))
59 | t.start()
60 |
61 |
62 | def deal_data(conn, addr):
63 | print('Accept new connection from {0}'.format(addr))
64 | txtMsgList.insert(END, '文件系统收到一个新的连接,地址来自 {0}'.format(addr), 'greencolor')
65 | # conn.settimeout(500)
66 | # 收到请求后的回复
67 | conn.send('你好,连接建立成功了'.encode('utf-8'))
68 |
69 | while True:
70 | # 申请相同大小的空间存放发送过来的文件名与文件大小信息
71 | fileinfo_size = struct.calcsize('128sl')
72 | # 接收文件名与文件大小信息
73 | buf = conn.recv(fileinfo_size)
74 | # 判断是否接收到文件头信息
75 | if buf:
76 | # 获取文件名和文件大小
77 | filename, filesize = struct.unpack('128sl', buf)
78 | fn = filename.strip(b'\00')
79 | fn = fn.decode()
80 | print('file new name is {0}, filesize if {1}'.format(str(fn), filesize))
81 | txtMsgList.insert(END, '收到的文件名字为 {0}, 文件大小为 {1}'.format(str(fn), filesize), 'greencolor')
82 | recvd_size = 0 # 定义已接收文件的大小
83 | # 存储在该脚本所在目录下面
84 | fp = open('./' + str(fn), 'wb')
85 | print('start receiving...')
86 | txtMsgList.insert(END, '开始接受...', 'greencolor')
87 | # 将分批次传输的二进制流依次写入到文件
88 | while not recvd_size == filesize:
89 | if filesize - recvd_size > 1024:
90 | lens=conn.recv(1024).decode('utf-8')
91 | lens=int(lens)
92 | print('该段发送长度为',lens)
93 | data = conn.recv(lens)
94 | data=fileDecrypt(data)
95 | recvd_size += len(data)
96 | else:
97 | lens = conn.recv(1024).decode('utf-8')
98 | lens = int(lens)
99 | print('该段发送长度为', lens)
100 | data = conn.recv(lens)
101 | data = fileDecrypt(data)
102 | recvd_size = filesize
103 | conn.send('I have receive the past one'.encode('utf-8'))
104 | fp.write(data)
105 | fp.close()
106 | print('end receive...')
107 | txtMsgList.insert(END, '接收完毕...', 'greencolor')
108 | # 传输结束断开连接
109 | conn.close()
110 | break
111 |
112 |
113 | def mainPage():
114 | def sendMsg(Sock): # 发送消息
115 | strMsg = "我:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n'
116 | txtMsgList.insert(END, strMsg, 'greencolor')
117 | Mes = txtMsg.get('0.0', END)
118 | txtMsgList.insert(END, Mes)
119 | print(Mes)
120 | onceKey = AESalgorithm.genKey() # 一次一密 密钥
121 | print("oncekey", onceKey)
122 | digest = RSAalgorithm.RsaSignal(Mes, SERVERPRIVATEs) # 先hash再签名# 生成消息摘要
123 | message = {'Message': Mes, 'digest': digest.decode("utf-8")} # 把消息和摘要打包
124 | message = json.dumps(message) # 转成json字符串
125 | message = AESalgorithm.AesEncrypt(message, onceKey) # 合并加密
126 | encrykey = RSAalgorithm.RsaEncrypt(onceKey, CLIENTPUBLICs) # 用服务器公钥加密一次密钥
127 | txtMsg.delete('0.0', END)
128 | Message = pickle.dumps([message, encrykey.decode('utf-8')]) # 序列化消息,用于传输
129 | Sock.send(Message)
130 |
131 | def RecvMsg(Sock, test):
132 | global CLIENTPUBLICs
133 | while True:
134 | Message = Sock.recv(BUFF) # 收到文件
135 | (message, encrykey) = pickle.loads(Message)
136 | mykey = RSAalgorithm.RsaDecrypt(encrykey, SERVERPRIVATEs) # 用私钥解密获得一次密钥
137 | decryMes = AESalgorithm.AesDecrypt(message, mykey.decode('utf-8')) # 用一次密钥解密消息,获得包含消息内容和摘要的json
138 | decryMes = json.loads(decryMes) # 将json转换为python字典
139 | content = decryMes['Message']
140 | digest = decryMes['digest'].encode('utf-8')
141 | if RSAalgorithm.VerRsaSignal(content, digest, CLIENTPUBLICs):
142 | strMsg = "对方:" + time.strftime("%Y-%m-%d %H:%M:%S",
143 | time.localtime()) + "通过数字签名认证,本次密钥为" + mykey.decode('utf-8') + '\n'
144 | txtMsgList.insert(END, strMsg, 'greencolor')
145 | txtMsgList.insert(END, content + '\n')
146 |
147 |
148 | def cancelMsg(): # 取消信息
149 | txtMsg.delete('0.0', END)
150 |
151 | def sendMsgEvent(event, Sock): # 发送消息事件
152 | if event.keysym == 'Up':
153 | sendMsg(Sock)
154 |
155 | def UploadAction(event=None):
156 | filename = filedialog.askopenfilename()
157 | print('Selected:', filename)
158 |
159 | def addSysTip(mes):
160 | global txtMsgList
161 | txtMsgList.insert(END, "系统消息:" + mes)
162 |
163 | def exchangePublicKey(dir):
164 | global ConSock, txtMsgList
165 | with open(dir, 'rb') as fi:
166 | publicKey = fi.read()
167 | # print(publicKey)
168 | has = hashalg.hash_sha256(publicKey)
169 | Message = pickle.dumps([publicKey, has])
170 | try:
171 | ConSock.send(Message)
172 | txtMsgList.insert(END, "发送公钥成功\n")
173 | except:
174 | txtMsgList.insert(END, "密钥发送失败,正在尝试重新发送...\n")
175 | exchangePublicKey(dir)
176 |
177 | def verifyKey(Sock):
178 | global txtMsgList, CLIENTPUBLICs
179 | while True:
180 | Message = Sock.recv(BUFF)
181 | # print("shoudao:",Message)
182 | (publickey, hash_256) = pickle.loads(Message)
183 | if hash_256 == hashalg.hash_sha256(publickey):
184 | txtMsgList.insert(END, "公钥完整性验证完成,可以开始传输文件\n")
185 | CLIENTPUBLICs = publickey
186 | txtMsgList.insert(END, "收到公钥\n" + CLIENTPUBLICs.decode('utf-8') + "\n")
187 | # print("publicc:", CLIENTPUBLICs)
188 | break
189 | else:
190 | txtMsgList.insert(END, "验证失败\n")
191 |
192 | def cnct():
193 | global txtMsgList, ConSock
194 | HOSTIP = '127.0.0.1'
195 | ServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
196 | ServerSock.bind((HOSTIP, PORT))
197 | ServerSock.listen(8)
198 | print("本机IP地址为", HOSTIP, "端口号为", PORT, ",正在监听中")
199 | txtMsgList.insert(END, "系统消息:" + "本机IP地址为" + HOSTIP + "端口号为" + str(PORT) + ",正在监听中\n")
200 | ConSock, addr = ServerSock.accept()
201 | print('连接成功')
202 | txtMsgList.insert(END, "系统消息:连接成功\n")
203 | exchangePublicKey("keys/server/serverpublic.pem")
204 | verifyKey(ConSock)
205 | thread_rev = threading.Thread(target=RecvMsg, args=(ConSock, None))
206 | thread_rev.start()
207 | return ConSock
208 |
209 | def setIpWindows():
210 | def setNewIP(newip, newport):
211 | print(newip, newport)
212 | global IP
213 | IP = str(newip)
214 | global PORT
215 | PORT = int(newport)
216 | set.destroy()
217 | try:
218 | cnct()
219 | except:
220 | addSysTip("连接异常,ip或端口不可访问")
221 | tkinter.messagebox.showwarning('连接失败', '连接异常,ip或端口不可访问\n')
222 | print("连接异常,ip或端口不可访问\n")
223 |
224 | set = Tk()
225 | set.title('设置ip地址和端口号')
226 | set.geometry('350x200')
227 | set.resizable(0, 0)
228 | # ip
229 | Label(set, text='IP地址:').place(x=10, y=10)
230 | ent1 = Entry(set)
231 | ent1.place(x=150, y=10)
232 | # port
233 | Label(set, text='端口号:').place(x=10, y=50)
234 | ent2 = Entry(set)
235 | ent2.place(x=150, y=50)
236 | bt_connect = Button(set, text='连接', command=lambda: setNewIP(ent1.get(), ent2.get()))
237 | bt_connect.place(x=150, y=130)
238 | set.mainloop()
239 |
240 | def start():
241 | global app, frmLT, frmLC, frmLB, txtMsgList, txtMsg, btnSend, btnCancel, btnFile, btnSet
242 | # 创建窗口
243 | app = Tk()
244 | app.title('Server')
245 | app.resizable(0, 0)
246 |
247 | # 创建frame容器
248 | frmLT = Frame(width=500, height=320, bg='white')
249 | frmLC = Frame(width=500, height=150, bg='white')
250 | frmLB = Frame(width=500, height=30)
251 | # frmRT = Frame(width = 200, height = 500)
252 |
253 | # 创建控件
254 | txtMsgList = Text(frmLT)
255 | txtMsgList.tag_config('greencolor', foreground='#008C00') # 创建tag
256 | txtMsg = Text(frmLC)
257 | txtMsg.bind("", sendMsgEvent)
258 | btnSend = Button(frmLB, text='发送', width=8, command=lambda: sendMsg(ServerSocket))
259 | btnCancel = Button(frmLB, text='取消', width=8, command=cancelMsg)
260 | btnFile = Button(frmLB, text='上次文件', width=8, command=UploadAction)
261 | btnSet = Button(frmLB, text='设置ip', width=8, command=setIpWindows)
262 | # btnFile.pack()
263 | # imgInfo = PhotoImage(file = "timg-2.gif")
264 | # lblImage = Label(frmRT, image = imgInfo)
265 | # lblImage.image = imgInfo
266 |
267 | # 窗口布局
268 | frmLT.grid(row=0, column=0, columnspan=2, padx=1, pady=3)
269 | frmLC.grid(row=1, column=0, columnspan=2, padx=1, pady=3)
270 | frmLB.grid(row=2, column=0, columnspan=2)
271 | # frmRT.grid(row = 0, column = 2, rowspan = 3, padx =2, pady = 3)
272 |
273 | # 固定大小
274 | frmLT.grid_propagate(0)
275 | frmLC.grid_propagate(0)
276 | frmLB.grid_propagate(0)
277 | # frmRT.grid_propagate(0)
278 |
279 | btnSend.grid(row=2, column=0)
280 | btnCancel.grid(row=2, column=1)
281 | btnFile.grid(row=2, column=2)
282 | btnSet.grid(row=2, column=3)
283 | # lblImage.grid()
284 | txtMsgList.grid()
285 | txtMsg.grid()
286 | # 主事件循环
287 | app.mainloop()
288 |
289 | thread_gui = threading.Thread(target=start)
290 | thread_gui.start()
291 |
292 | ServerSocket = cnct()
293 | # try:
294 | # ServerSocket=cnct()
295 | # except:
296 | # addSysTip("连接异常,ip或端口不可访问")
297 | # tkinter.messagebox.showwarning('连接失败', '连接异常,ip或端口不可访问,点击设置按钮重新设置\n')
298 | # print("连接异常,ip或端口不可访问\n")
299 |
300 |
301 | def main():
302 | initKey()
303 | thread_1=threading.Thread(target=initFileListen)
304 | # thread_2=threading.Thread(target=mainPage)
305 | mainPage()
306 | thread_1.start()
307 | # thread_2.start()
308 |
309 |
310 | if __name__ == "__main__":
311 | main()
312 |
--------------------------------------------------------------------------------
/algorithms/AESalgorithm.py:
--------------------------------------------------------------------------------
1 | import base64
2 | from Crypto.Cipher import AES
3 | import random
4 | import string
5 |
6 | # 采用AES对称加密算法,CBC
7 |
8 |
9 | iv=b'0000100010010010'
10 | # str不是16的倍数那就补足为16的倍数
11 | def add_to_16(value):
12 | if isinstance(value,bytes):
13 | value.decode()
14 | while len(value) % 16 != 0:
15 | value += '\0'
16 | return str.encode(value) # 返回bytes
17 | #加密方法
18 | def AesEncrypt(data,key):
19 | if isinstance(data,bytes):
20 | text=base64.b64encode(data).decode('ascii')
21 | else:
22 | text = base64.b64encode(data.encode('utf-8')).decode('ascii')
23 | # 初始化加密器
24 | aes = AES.new(add_to_16(key), AES.MODE_CBC,IV=iv)
25 | #先进行aes加密
26 | encrypt_aes = aes.encrypt(add_to_16(text))
27 | #用base64转成字符串形式
28 | encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 执行加密并转码返回bytes
29 | return encrypted_text
30 | #解密方法
31 | def AesDecrypt(text,key):
32 | # 初始化加密器
33 | aes = AES.new(add_to_16(key), AES.MODE_CBC,IV=iv)
34 | #优先逆向解密base64成bytes
35 | if isinstance(text,str):
36 | base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
37 | else:
38 | base64_decrypted=base64.decodebytes(text)
39 | decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8') # 执行解密密并转码返回str
40 | decrypted_text = base64.b64decode(decrypted_text.encode('utf-8'))\
41 | # .decode('utf-8')
42 | return decrypted_text
43 |
44 |
45 | def genKey():
46 | source=string.ascii_letters+string.digits
47 | key="".join(random.sample(source,16))
48 | return key
49 |
50 | if __name__ == '__main__':
51 | text='你好你好'
52 | mykey=genKey()
53 | print("加密密钥是"+mykey)
54 | e=AesEncrypt(text,mykey)
55 | d=AesDecrypt(e,mykey)
56 | print(e)
57 | print(d)
--------------------------------------------------------------------------------
/algorithms/RSAalgorithm.py:
--------------------------------------------------------------------------------
1 | from Crypto import Random
2 | from Crypto.Hash import SHA
3 | from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
4 | from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
5 | from Crypto.PublicKey import RSA
6 | import base64
7 | random_generator= Random.new().read
8 | print("rand:",random_generator)
9 | def RsaEncrypt(message,key):
10 | rsakey = RSA.importKey(key) #生成RSA密钥对象
11 | cipher = Cipher_pkcs1_v1_5.new(rsakey) #生成一个pkcs1 对象
12 | if isinstance(message,str):
13 | message=message.encode('utf-8')
14 | cipher_text = base64.b64encode(cipher.encrypt(message)) #生成一个bytes对象
15 | print(cipher_text.decode('utf-8'))
16 | return cipher_text #返回一个bytes对象,如果要显示需要utf8编码
17 | def RsaDecrypt(encrypt_text,key):
18 | global random_generator
19 | rsakey = RSA.importKey(key)
20 | cipher = Cipher_pkcs1_v1_5.new(rsakey)
21 | if isinstance(encrypt_text,str):
22 | encrypt_text=base64.b64decode(encrypt_text)
23 | text = cipher.decrypt(encrypt_text,random_generator)
24 | print("测试点test",type(text))
25 | return text #返回bytes对象,显示需要utf8编码
26 |
27 | def RsaSignal(message,key):
28 | if isinstance(message,str):
29 | message=message.encode()
30 | rsakey = RSA.importKey(key)
31 | signer = Signature_pkcs1_v1_5.new(rsakey)
32 | digest = SHA.new()
33 | digest.update(message)
34 | sign = signer.sign(digest)
35 | signature = base64.b64encode(sign)
36 | print(signature)
37 | return signature
38 |
39 | def VerRsaSignal(message,signature,key):
40 | if isinstance(message,str):
41 | message=message.encode()
42 | print("signtype",type(signature))
43 | rsakey = RSA.importKey(key)
44 | verifier = Signature_pkcs1_v1_5.new(rsakey)
45 |
46 | digest = SHA.new()
47 | # Assumes the data is base64 encoded to begin with
48 | digest.update(message)
49 |
50 | is_verify = verifier.verify(digest, base64.b64decode(signature))
51 | print(is_verify)
52 | return is_verify
53 |
54 | if __name__ == '__main__':
55 | mes='你好yo'
56 | pubkey='''-----BEGIN PUBLIC KEY-----
57 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSChFb9Y6xwb+XTMIcHR
58 | Q5lujD1J7v93TwJvUE7e6SEVpQEjfFKpjVEFpJUONdagBRYYkO4TA6k9gpAPmPCF
59 | nucttQBMAkTMDtxLndOKI0MOc5THw0h1fschm6CyJzkGoVYlPr0vU2Oq10yK0s7y
60 | uYqTzJB5sOLjRCGxdIw9V3UmpggK+IfQ6yXrM/dXy4h13zR6IzHnJ8tBH0VvvPes
61 | z/fMrN/HWw6av13CZuS12qEU/Jij+8ZvpKxn6kd1BO4+g9UW4ExsEq95+qFTOJIj
62 | hlm7yJCCsHfNq/r1nIa/NbpigQG0TS26r8sWTLgPmYysBTONFwX+NtCbbESRwRMo
63 | gQIDAQAB
64 | -----END PUBLIC KEY-----'''
65 | prikey='''-----BEGIN RSA PRIVATE KEY-----
66 | MIIEowIBAAKCAQEAvSChFb9Y6xwb+XTMIcHRQ5lujD1J7v93TwJvUE7e6SEVpQEj
67 | fFKpjVEFpJUONdagBRYYkO4TA6k9gpAPmPCFnucttQBMAkTMDtxLndOKI0MOc5TH
68 | w0h1fschm6CyJzkGoVYlPr0vU2Oq10yK0s7yuYqTzJB5sOLjRCGxdIw9V3UmpggK
69 | +IfQ6yXrM/dXy4h13zR6IzHnJ8tBH0VvvPesz/fMrN/HWw6av13CZuS12qEU/Jij
70 | +8ZvpKxn6kd1BO4+g9UW4ExsEq95+qFTOJIjhlm7yJCCsHfNq/r1nIa/NbpigQG0
71 | TS26r8sWTLgPmYysBTONFwX+NtCbbESRwRMogQIDAQABAoIBABCU9cqkVjV253T9
72 | qpAjICffIfQlw3+y4lEJE51k7OJfxjgLW4Mg9ECxo98EOpS51pnbkBfU59HgWsZB
73 | vzxXij+eYUGHXyKryYBcDD0wOOJSlMfJeaJDjhmpd+bfNf9+Xnhyxx0zFR0olef+
74 | jAVjo6Bk6AR9fk3l9qsYkSh4y0AJnJuPnMjISqjn6LfGXf1VAVCkHljLRTHzIzw3
75 | ZbV1rNWNQq8znaNGQP1sGAXpu1x+XfQFJZVUDtVeC9E2bB3TQe5D+LIFCtZrUkpK
76 | PNOCqce9oOUgErUub73+fTMMvBX5rU2m6zuhmZjl9s8PHVsDv1/GMyU/6Krrhh8E
77 | n11ipEkCgYEAw+oFfJhs4DtC+IqC0WaI4v6BB4EoYDoaAhHjNQZ0gx5k1AtIeNpN
78 | YKCFF0IPyIQbDWve+hspxJ47zcOZuS85UfRFjkfohwYE4UdhViUAwsIiFePZMEz8
79 | 3R2XGL0lHbXnZ2KRD0u9w+u9YfPLngsnHBUZxRp7iG48apP2nYfRCrcCgYEA9yHC
80 | NOVb7ER9NMrSRkCCh6qM0jPUsCFFBPv63s6ZKKioyqHYUPVPP9ZxxsQpya+NUPiS
81 | vf56ccGFqtjKMDIMQh+POTPkFEyjFHwoxXxg76xz2uCpyQVsSQTNCwy9LkEavjNe
82 | sebB+a8iH2gTL5zIXObaTBC4iANhQ+OtR6BDjocCgYAVT6qjIA2P4sJpON/8GVRA
83 | pQCyKUmUFh3oJbv6c6ZO8Qp0ynlqtAyAu1Ve70+6NyyeLCLIQBYuDixhOKrLKyjo
84 | ElNSo93WekAjpVkgPswzY1zD1tI0X9uNzf82sLSN49C1PVKcQFf3LPif5B49Jedu
85 | NZllCHlxoNQvn8LO5gxGRwKBgQCD+CYSQyy8VbKa33g8hbRuqBe9JGp+h7WovLqy
86 | ApdtS+ufEaBHU0g3qddmMliyWCnZxHPwO5W9a39qxYvrAr7jDKFaBajVYjtv9AF9
87 | vDazpl7T0kc4jsnNkF/Cd9IKgj+6tAnsbHLHV8ucA+LC+TFR0wFdv0wbbdqh+1IM
88 | Prv0vwKBgFUAow5ttHgBtG5Ap4evsRgWzGaF2wOGzEOK3rwS5fIGY67A1YN35Q+C
89 | SmkGVcozf8rFeyMCwk68XoLff1i14iQDAarAjvdWo0ww/gjA50kdrgFb7FpjbZNE
90 | 0kOV6q4vFJIjT8g2CeJ1MmBEuHhflC+gNBWmlEs+xaghA7/cbop2
91 | -----END RSA PRIVATE KEY-----'''
92 | a=RsaEncrypt(mes,pubkey)
93 | b=RsaDecrypt(a,prikey)
94 | c=RsaSignal(mes,prikey)
95 |
96 |
97 |
98 |
99 | digitttt='IUvR9162yrRtQAfhhVZrefB9yCwSL+kf81iudLqcDyKesokwvhjZeOpUlXR7zYOokThhelPrqtE4DIsXIxNb7FY9QgwLFkCGSQG17h09FJaZQmDLaUmtDutXDFgGZ9j5Mzln1nCtOWDreey9YbeJaRsDRj4jjp1ZOCdsC8pN65M='
100 | digitttt=digitttt.encode('utf-8')
101 | pppuuu='''-----BEGIN PUBLIC KEY-----
102 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsCp6xhC5Tr7ucaRNU3aKMsvv8
103 | PtxlQdl4LTys5F6wKM11MeJSXwruiUBbDHhySLfy5ZPpYxsfa5ez6hbaZoMyk+xd
104 | p1jWehUWqouFA/OmHxQ4jjmhxJ40cNcm/TAkyl8zci0uGaird26x2NUa4o8BpnE5
105 | TokPhvYzdhsx05FQuwIDAQAB
106 | -----END PUBLIC KEY-----'''
107 | pppuuu=pppuuu.encode('utf-8')
108 | mess='你好,世界'
109 | d = VerRsaSignal(mess, digitttt, pppuuu)
110 | print("d",d)
--------------------------------------------------------------------------------
/algorithms/__pycache__/AESalgorithm.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/algorithms/__pycache__/AESalgorithm.cpython-38.pyc
--------------------------------------------------------------------------------
/algorithms/__pycache__/RSAalgorithm.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/algorithms/__pycache__/RSAalgorithm.cpython-38.pyc
--------------------------------------------------------------------------------
/algorithms/generateKey.py:
--------------------------------------------------------------------------------
1 | import Crypto.PublicKey.RSA
2 | import Crypto.Random
3 | #生成密钥
4 | #利用库中默认的generate来生成
5 | def generateMyKey(dir):
6 | x = Crypto.PublicKey.RSA.generate(1024)
7 | privateKey = x.exportKey("PEM") # 生成私钥
8 | publicKey = x.publickey().exportKey() # 生成公钥
9 | with open(dir+"private.pem", "wb") as x:
10 | x.write(privateKey)
11 | with open(dir+"public.pem", "wb") as x:
12 | x.write(publicKey)
13 | return(privateKey,publicKey)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/algorithms/hashalg.py:
--------------------------------------------------------------------------------
1 | import hashlib
2 | #hash函数
3 | def hash_sha256(datas): #sha256 哈希函数
4 | x=hashlib.sha256()
5 | x.update(datas)
6 | s=x.hexdigest()
7 | return s
8 |
9 | if __name__ == '__main__':
10 | e=hash_sha256('你好'.encode('utf-8'))
11 | print(e)
--------------------------------------------------------------------------------
/img.assets/clip_image002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image002.png
--------------------------------------------------------------------------------
/img.assets/clip_image004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image004.png
--------------------------------------------------------------------------------
/img.assets/clip_image006.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image006.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image008.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image008.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image010.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image010.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image012.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image012.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image014.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image014.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image016.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image016.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image018.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image018.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image020.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image020.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image022.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image022.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image024.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image024.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image026.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image026.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image028.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image028.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image030.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image030.jpg
--------------------------------------------------------------------------------
/img.assets/clip_image032.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenjunjiecn/Cybersecurity-EncryptChatProject/7a0201a0d8b7ca0aa2ae073bd6df70e089803401/img.assets/clip_image032.jpg
--------------------------------------------------------------------------------
/keys/client/clientprivate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXAIBAAKBgQC0oO4QTVvWto0ddIRNTx5de6bfGm75B4Q3yoXaDYVn7G76hdtF
3 | vGvM3VPjtX3YwT2Skcn+p1XqCdA2JkoGueigKgy5EpkvNPitaenDumbzbaTu8f+f
4 | VtlMuwt5g0eTcsYee1je4e0PfYx0txGOi/wMuZ2zXcHeuDwOP5p1t1G6qwIDAQAB
5 | AoGAAsCC8Aelsw9D9iNs0pq2fTkhkTufXjbxmkIBKRHUqwEsra91aEoXIF9s5EbD
6 | HJbRH9cNy030XqT4oaKStSiG9UcwezsFpq/eLrQe5y1Y8XOZKteFHGzX+9GkG6Bc
7 | qGpmU9RFL6Yww4qMv3LdhGV2vdkcVDFuC6yQmnukYpfTVLUCQQDQhbdTeMQ0ay9/
8 | 3gJP0SwZ/CVpQiMRTSKcw1Z92QLHTfWWyUvLIskvFHfTj7pB20bsQpmzjK4DngIX
9 | wuH2O2WXAkEA3cFa1t9e8nwq5WdWLvHfScIOdB0AtLauw+zLmg/jVszWDjgrB00Z
10 | fKwIyBUu7Sc7Af9daYmkb1KHq4eGXkU+DQJAWSL/5ge2361+BYvyswn4bzcxCtjB
11 | wtCVXivGWk+c93Ok6wsrgi9hjuWR/3buKN7CZ5Zku7MEY/l0bZHaI/bqCwJAYm8o
12 | xoaim9qYI/qJ3A7Lge8dAVe6b31D+H5NJlb1IBuOzQMLvpLvxFKNF1un1+d5Hvre
13 | 2TEbB7tHs9FVyNTNpQJBAKw/gyv2gauM9egKc0ohlrVpz92hzCotqY94VpMWceXz
14 | aVyCHzBEzTfDAwBob63/C8F4LDBmwULB81nePoy7x3E=
15 | -----END RSA PRIVATE KEY-----
--------------------------------------------------------------------------------
/keys/client/clientpublic.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0oO4QTVvWto0ddIRNTx5de6bf
3 | Gm75B4Q3yoXaDYVn7G76hdtFvGvM3VPjtX3YwT2Skcn+p1XqCdA2JkoGueigKgy5
4 | EpkvNPitaenDumbzbaTu8f+fVtlMuwt5g0eTcsYee1je4e0PfYx0txGOi/wMuZ2z
5 | XcHeuDwOP5p1t1G6qwIDAQAB
6 | -----END PUBLIC KEY-----
--------------------------------------------------------------------------------
/keys/server/serverprivate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXAIBAAKBgQCZlWShX2hGOY2XgNP8SDf7UxdQa8oeK8iEPe571jrdduHYvDTG
3 | Oj5XA+3X9LwZafMQmTBaJcvgtezT0ObTxm8mm6pyftWVtG2uuGFqsGECA5lq0vWz
4 | 6VUoOHUPBP+BwmKPqo5p/o7howp0lpDuqxjTYixM1WbWFTbl6pNUsJzC5QIDAQAB
5 | AoGAG7s7Z937zI5Q0DXdURTTMuiucYF9BdSfCK3MFYU5rMpt/j4Bg3d50Slu9UsF
6 | +crFLk6SyfxAI2uF/zsdqsiOQhEm0R/aPGNJaxfmecF60rXLXnz4XenMXQQByCMZ
7 | ZbTY/yyi09IwZVaSPkAvRm3HGTn+uHw5Xlqy5cZkYwb+1sMCQQC626B4kfdIxXGf
8 | xW3AcMXY474Ai9iTTa49hfyYiEseD7p1C0edxddGz8HnJj6DZXWI4CTxGnCOdg7j
9 | 4P+pOkmjAkEA0mnOwQ/E2hmyuKyRFZyH6fsD4OwBpTk0gc0uEum+0cgu65ctvDx5
10 | 6gNzK7urr8ZWzhpxRhiHUQKd/nYpCigZ1wJAQ55ev8LynZ71sz+aq90je41OoJv6
11 | z7N4rkLiWcBYjpRagSiHzgxeDv33yVIJpTr+AX47YBSVTrhiQwyU+ARjyQJBAJR2
12 | JXShDLMaiLi2wdOu01MrUmxD+VE70Kl5PPYJSSM5jKmbzKBRR2/vKTcFPrlSR3M6
13 | wwvDSM7G+vVNJ93Lt5cCQBqvn3S9tZHmsgWGZU6E9xGTxAf9eRME4P99yXVBk6MV
14 | kK3sOJZcKDKaGHX4AShxTb+yMV6FkBlj/+l+CqznxVE=
15 | -----END RSA PRIVATE KEY-----
--------------------------------------------------------------------------------
/keys/server/serverpublic.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZlWShX2hGOY2XgNP8SDf7UxdQ
3 | a8oeK8iEPe571jrdduHYvDTGOj5XA+3X9LwZafMQmTBaJcvgtezT0ObTxm8mm6py
4 | ftWVtG2uuGFqsGECA5lq0vWz6VUoOHUPBP+BwmKPqo5p/o7howp0lpDuqxjTYixM
5 | 1WbWFTbl6pNUsJzC5QIDAQAB
6 | -----END PUBLIC KEY-----
--------------------------------------------------------------------------------
/test/client.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import threading
3 | import pickle
4 | from algorithms import RSAalgorithm
5 |
6 | PORT = 4396
7 | BUFF = 1024
8 |
9 | def SendMessage(Sock, test):
10 | while True:
11 | SendData = input()
12 | (encryptdata, PrivateKey) = RSAalgorithm.RsaEncrypt(SendData)
13 | print('encrypted data is ' + str(encryptdata))
14 | Message = pickle.dumps([encryptdata, PrivateKey])
15 | if len(SendData) > 0:
16 | Sock.send(Message)
17 |
18 |
19 | def RecvMessage(Sock, test):
20 | while True:
21 | Message = Sock.recv(BUFF)
22 | (recvdata, PrivateKey) = pickle.loads(Message)
23 | decryptdata = RSAalgorithm.RsaDecrypt(recvdata, PrivateKey)
24 | if len(Message) > 0:
25 | print("receive message:" + decryptdata)
26 |
27 | #获取本机ip地址
28 | def get_host_ip():
29 | try:
30 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
31 | s.connect(('8.8.8.8', 80))
32 | ip = s.getsockname()[0]
33 | finally:
34 | s.close()
35 |
36 | return ip
37 |
38 |
39 | def main():
40 | type = input('您是server还是client?')
41 | if type == 'server':
42 | IPADD=get_host_ip()
43 | print("您的ip地址为:",IPADD)
44 | ServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45 | ServerSock.bind((IPADD, PORT))
46 | ServerSock.listen(5)
47 | print("正在监听中...")
48 | while True:
49 | ConSock, addr = ServerSock.accept()
50 | print('connection succeed' + '\n' + 'you can chat online')
51 | thread_1 = threading.Thread(target=SendMessage, args=(ConSock, None))
52 | thread_2 = threading.Thread(target=RecvMessage, args=(ConSock, None))
53 | thread_1.start()
54 | thread_2.start()
55 | elif type == 'client':
56 | ClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
57 | ServerAddr = input("请输入您要通讯的ip地址")
58 | ClientSock.connect((ServerAddr, PORT))
59 | print('连接成功,可以开始传输消息和文件了')
60 | thread_3 = threading.Thread(target=SendMessage, args=(ClientSock, None))
61 | thread_4 = threading.Thread(target=RecvMessage, args=(ClientSock, None))
62 | thread_3.start()
63 | thread_4.start()
64 |
65 |
66 | if __name__ == '__main__':
67 | main()
68 |
--------------------------------------------------------------------------------
/test/tclient.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import threading
3 | import pickle
4 | from algorithms import RSAalgorithm
5 |
6 | PORT = 4396
7 | BUFF = 1024
8 |
9 |
10 | def SendMessage(Sock, test):
11 | while True:
12 | SendData = input()
13 | (encryptdata, PrivateKey) = RSAalgorithm.RsaEncrypt(SendData)
14 | print('encrypted data is ' + str(encryptdata))
15 | Message = pickle.dumps([encryptdata, PrivateKey])
16 | if len(SendData) > 0:
17 | Sock.send(Message)
18 |
19 |
20 | def RecvMessage(Sock, test):
21 | while True:
22 | Message = Sock.recv(BUFF)
23 | (recvdata, PrivateKey) = pickle.loads(Message)
24 | decryptdata = RSAalgorithm.RsaDecrypt(recvdata, PrivateKey)
25 | if len(Message) > 0:
26 | print("receive message:" + decryptdata)
27 |
28 |
29 | # 获取本机ip地址
30 | def get_host_ip():
31 | try:
32 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
33 | s.connect(('8.8.8.8', 80))
34 | ip = s.getsockname()[0]
35 | finally:
36 | s.close()
37 |
38 | return ip
39 |
40 |
41 | def main():
42 | ClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
43 | # ServerAddr = input("请输入您要通讯的ip地址")
44 | ServerAddr ="127.0.0.1"
45 | ClientSock.connect((ServerAddr, PORT))
46 | print('连接成功,可以开始传输消息和文件了')
47 | thread_3 = threading.Thread(target=SendMessage, args=(ClientSock, None))
48 | thread_4 = threading.Thread(target=RecvMessage, args=(ClientSock, None))
49 | thread_3.start()
50 | thread_4.start()
51 |
52 |
53 |
54 | if __name__ == '__main__':
55 | main()
56 |
--------------------------------------------------------------------------------
/test/tserver.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import threading
3 | import pickle
4 | from algorithms import RSAalgorithm
5 |
6 | HOSTIP='127.0.0.1'
7 | PORT = 4396
8 | BUFF = 1024
9 |
10 |
11 | def SendMessage(Sock, test):
12 | while True:
13 | SendData = input()
14 | (encryptdata, PrivateKey) = RSAalgorithm.RsaEncrypt(SendData)
15 | print('encrypted data is ' + str(encryptdata))
16 | Message = pickle.dumps([encryptdata, PrivateKey])
17 | if len(SendData) > 0:
18 | Sock.send(Message)
19 |
20 |
21 | def RecvMessage(Sock, test):
22 | while True:
23 | Message = Sock.recv(BUFF)
24 | (recvdata, PrivateKey) = pickle.loads(Message)
25 | decryptdata = RSAalgorithm.RsaDecrypt(recvdata, PrivateKey)
26 | if len(Message) > 0:
27 | print("receive message:" + decryptdata)
28 |
29 |
30 | # 获取本机ip地址
31 | def get_host_ip():
32 | try:
33 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
34 | s.connect(('8.8.8.8', 80))
35 | ip = s.getsockname()[0]
36 | finally:
37 | s.close()
38 |
39 | return ip
40 |
41 |
42 | def main():
43 | HOSTIP = '127.0.0.1'
44 | ServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45 | ServerSock.bind((HOSTIP, PORT))
46 | ServerSock.listen(8)
47 | print("本机IP地址为",HOSTIP,"端口号为",PORT,",正在监听中")
48 | while True:
49 | ConSock, addr = ServerSock.accept()
50 | print('connection succeed' + '\n' + 'you can chat online')
51 | thread_1 = threading.Thread(target=SendMessage, args=(ConSock, None))
52 | thread_2 = threading.Thread(target=RecvMessage, args=(ConSock, None))
53 | thread_1.start()
54 | thread_2.start()
55 |
56 |
57 |
58 |
59 |
60 | if __name__ == '__main__':
61 | main()
62 |
--------------------------------------------------------------------------------