這次設計的程式碼只實現:
1.對稱加密金鑰的安全傳輸
2.對稱加密
3.非對稱加密
4.互動介面
對稱加密採用DES,非對稱加密採用RSA
其中RSA實現DES金鑰的加密傳輸,DES實現資訊的加密傳輸(因為效率高)
程式碼如下:
import rsa from tkinter import * import tkinter.messagebox import tkinter as tk from pyDes import des, CBC, PAD_PKCS5 import binascii import numpy as np from PIL import Image from PIL import ImageTk # DES金鑰 with open('key.txt','r') as f: KEY = f.read() key = rsa.newkeys(1024) # 生成隨機金鑰 privateKeyB = key[1] # B的私鑰 publicKeyB = key[0] # B的公鑰 def des_encrypt(s): """ DES 加密 :param s: 原始字串 :return: 加密後字串,16進位制 """ secret_key = KEY iv = secret_key k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) en = k.encrypt(s, padmode=PAD_PKCS5) return binascii.b2a_hex(en) def des_descrypt(s): """ DES 解密 :param s: 加密後的字串,16進位制 :return: 解密後的字串 """ secret_key = KEY iv = secret_key k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5) return de def main1(): # RSA加解密 # 公鑰加密 message = KEY print('加密的DES的祕鑰:', message) message = message.encode() global cryptedMessage cryptedMessage = rsa.encrypt(message, publicKeyB) print("加密後的對稱金鑰的bytes形式:",cryptedMessage) with open("miku.txt", "w") as f: f.write(cryptedMessage.hex()) print('加密後的對稱金鑰的十六進位制形式:', cryptedMessage.hex()) txt1.insert(END, 'DES加密後結果: ') txt1.insert(END, '\n') txt1.insert(END, cryptedMessage.hex()) txt1.insert(END, '\n' + '\n' + '\n') txt1.update() #傳送的密文 with open('bbb.txt','r') as f: s=f.read() print("\n") enc = des_encrypt(s) print ("DES加密後的密文:") print(enc) enc1 = str(enc, encoding="utf8") with open('aaa.txt','w') as f: f.write(enc1) txt1.insert(END, 'Alice傳送的密文: ') txt1.insert(END, '\n') txt1.insert(END, enc1) txt1.insert(END, '\n'+'\n'+'\n') txt1.update() tk.messagebox.askokcancel(title='提示', message='Alice傳輸密文成功\n請等待圖片加密完成,約20秒左右') #圖片轉二進位制 im = Image.open('QQ.jpg') im2 = np.array(im) np.save(file="out.npy", arr=im2) #加密二進位制 with open('out.npy','rb') as f: ai=f.read() encc = des_encrypt(ai) with open('oout.npy','wb') as f: f.write(encc) print("DES加密後的圖片二進位制:") print(encc) print('\n') tk.messagebox.askokcancel(title='提示', message='Alice傳輸圖片密文成功') def main2(): # RSA加解密 with open("miku.txt","r") as f: meassage1=f.read() print("檔案中對稱金鑰的十六進位制:",meassage1) meassage2=bytes(meassage1,encoding="utf-8") print("檔案中對稱金鑰的bytes形式:",meassage2) # 私鑰解密 message = rsa.decrypt(cryptedMessage, privateKeyB) message = message.decode() print('解密後:', message) txt2.insert(END, '解密得到DES的祕鑰:') txt2.insert(END, '\n') txt2.insert(END, message) txt2.insert(END, '\n'+'\n'+'\n') txt2.update() #傳送的密文 with open('aaa.txt','r') as f: s=f.read() print(s) print("\n") enc = s print ("DES加密後的密文:") print(enc) des = des_descrypt(enc) print ("DES解密後的明文:") print(des) des1 = str(des, encoding="utf8") txt2.insert(END, 'Bob解密的明文: ') txt2.insert(END, '\n') txt2.insert(END, des1) txt2.insert(END, '\n'+'\n'+'\n') txt2.update() print("\n") tk.messagebox.askokcancel(title='提示', message='Bob接收成功\n請等待,正在解密圖片') #解密圖片二進位制陣列 with open('oout.npy','rb') as f: ss=f.read() dess = des_descrypt(ss) with open('oout.npy','wb') as f: f.write(dess) #轉為圖片 ai2=np.load('oout.npy') print(ai2) image = Image.fromarray(ai2) image.save('yt.png') tk.messagebox.askokcancel(title='提示', message='圖片轉換成功,即將顯示') img = Image.open("yt.png") img.show() #TKinter root = tk.Tk() root.geometry('600x400') root.title('密碼學實驗互動介面') canvas = tk.Canvas(root, width=1900, height=750, bd=0, highlightthickness=0) imgpath = 'bg.jpeg' img = Image.open(imgpath) photo = ImageTk.PhotoImage(img) canvas.create_image(700, 500, image=photo) canvas.pack() btn1 = Button(root, text='Alice開始加密傳輸',bg='grey',command=main1,fg='white') txt1 = Text(root) txt1.place(relx=0.4, rely=0.1, relwidth=0.5, relheight=0.35) btn1.place(relx=0.05, rely=0.1, relwidth=0.3, relheight=0.2) btn2 = Button(root, text='Bob開始解密', bg='grey',command=main2,fg='white') txt2 = Text(root) txt2.place(relx=0.4, rely=0.5, relwidth=0.5, relheight=0.35) btn2.place(relx=0.05, rely=0.5, relwidth=0.3, relheight=0.2) root.mainloop()
在設計之初沒有去實現通訊,只是用寫入檔案、讀取檔案模擬傳輸過程,此外圖片加密傳輸是用三維陣列的二進位制傳輸的,其實用base64來實現會更加簡單
互動介面的話使用了python的tk來實現
實驗截圖:
最後會顯示圖片,實驗加密的是灰度圖,彩色圖片應該也能實現加密