密碼學課程設計 - 混合密碼的實現

ch0bits發表於2020-12-05

這次設計的程式碼只實現:

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來實現

 

實驗截圖:

 

最後會顯示圖片,實驗加密的是灰度圖,彩色圖片應該也能實現加密

相關文章