大家好,我是長風青雲。今天是第十九天,我們要進入的實例是Secret Talk。
先來說說前言和一些基本概念的部分吧。
在我大三的時候我修了一堂課叫做網路程式設計,與此同時我們也上了一堂叫做網路安全的課。
那個時候期末project我就一直在思考著要做什麼,如果我沒記錯……似乎是在上雲端運算概論的時候,我開始想著如果能在網路程式設計的期末project做出public key的聊天室就好了。
那個時候想的還不仔細,畢竟後來我做的是連線五子棋,但其實內心就一直想將所學到的東西放到現實裡來看看。
時隔……也沒多年,時隔一年多一些,我才打算將他做出來。
我以前想的是某個程式,他會是開機程式,然後如果有人希望能與你聊天,會傳送相應的port給你,同時你那邊會跳出通知。這個port會經過你的publickey加密過,所以只有你看的到他的port到底是多少,接著再開啟putty到相應的位置開始進行聊天。
看著就很亂吧XD,但現在我是打算用網頁的形式了。畢竟已經學了嘛~
那我們就來說什麼是public key吧!
網安不算學的好的我,在這我就簡單說明一些概念就好。
在密碼學我們擁有兩種加密模式,一個是對稱式加密,一個則稱為非對稱式加密。
對稱式加密意義是指加密與解密是使用同一把鑰匙,類似於你家的大門,打開和關上都是用同一個鑰匙。這意味著,A和B都必須知道這一把鑰匙,只要使用這把鑰匙別人就不知道你們互相傳遞的內容是什麼了。
但最初一開始,A和B要怎麼知道這把鑰匙是什麼呢?一定會有第一次A告訴B這把鑰匙內容的那一次吧?那如果這第一次就被C給攔截下來,C知道這把鑰匙那A和B的秘密不就都被知道了嗎?
所以後來衍生出了非對稱式加密。他的意義就代表是加密與解密的鑰匙是不同的。我來上個圖來方便解釋。
在這張圖裡面我看到Alice傳訊息給Bob,她是使用Bob的公鑰
進行上鎖,而Bob在收到密文後再使用自己的私鑰
解密。
那什麼是公鑰和私鑰呢?
私鑰很好理解,就是自己的鑰匙,自己需要好好保管。
而公鑰則是公布給大家知道的鑰匙,這樣他人要傳訊給自己時只要拿自己的公要進行上鎖,等密文到自己這裡再使用私鑰打開就好。
這樣說明大家應該會理解了吧~
至於算法部分我會之後在程式碼內部的時候跟大家說明,接下來我要說一下自己的想法。
我原先的想法……其實是當一個用戶註冊時,伺服器,也就是我們的Flask會順便算出你的公鑰私鑰,並將你的公鑰寫進我們的資料庫中。
但我發現這是不對的。
我這個主題是私密聊天室,資安問題需要放在優先考慮,倘若有人一直在監控著我們的網站,網路之間傳輸訊息被有心人攔截成功,那這公鑰、私鑰不就大白於天下了嗎?
所以我決定將我們的公私鑰寫成單機小程式,不連網的產生,這樣就不會有這方面的困擾了~
我網安學的不好,幸好自己有突然想到這一層……以前想的真的是太簡單了。那現在就先來寫我們的生成公鑰小程式吧~
我們採用tkinter這個module來設計我們的GUI
所以我們首先要pip install tkinter
,但是我不知道是因為我已經裝過還是我現在的python版本已經跟著下載下來了,反正先在cmd打就對了。
程式碼我擷取解釋。
from tkinter import Tk, Label, Entry, Button,StringVar
import tkinter.font as tkFont
import random
mainWin = Tk()
mainWin.title("RSA生成器")
mainWin.geometry("250x200")
跟我們的Flask相同,我們要先創建一個實例。
接著將我們的title和UI大小進行設定
ft = tkFont.Font(family='Fixdsys', size=20, weight=tkFont.BOLD)
firstNumLabel = Label(mainWin, text="公鑰",font=ft)
secondNumLabel = Label(mainWin, text="私鑰",font=ft)
public_key=StringVar()
private_key=StringVar()
firstNum = Entry(mainWin, text=public_key)
secondNum = Entry(mainWin, text=private_key)
這一段是將我們會使用的類別顯現出來。
我們需要用到兩個提醒我們此方框內容是什麼的Label(公鑰私鑰)
還需要兩個文字框,這樣到時候公鑰私鑰生成後我們可以直接複製貼上。
StringVar就放入我們的文字框內
def factor(n):
divisor = 2
factors = []
while divisor * divisor <= n:
if n % divisor:
divisor += 1
else:
n //= divisor
factors.append(divisor)
if n > 1:
factors.append(n)
if len(factors)==1:
factors=[1,1]
return factors
這是計算質因數的函式,此為此網站提供。
def cal():
prime=[10000000~9999999999的質數]
p,q=random.sample(prime,k=2)
n = p * q
fn = (p-1) * (q-1)
e,d=random.sample(factor(fn+1),k=2)
while e==d :
p,q=random.sample(prime,k=2)
n = p * q
fn = (p-1) * (q-1)
e,d=random.sample(factor(fn+1),k=2)
public_key.set("("+str(e)+","+str(n)+")")
private_key.set("("+str(d)+","+str(n)+")")
這就是我們計算公私鑰的程式碼,算式方法取自RSA計算器
prime部分太長,所以我就略減了。
Btn = Button(mainWin, text="生成",command=cal,font=ft)
接著不要忘記我們要生成公私鑰的按鈕,之所以不是放在上方跟大家一啟生出類別是因為上方無cal函式。
firstNumLabel.grid(row=0,column=0)
firstNum.grid(row=0,column=2)
secondNumLabel.grid(row=1,column=0)
secondNum.grid(row=1,column=2)
Btn.place(x=120,y=120)
mainWin.mainloop()
此部分為版面配置,配置好後就可以執行囉~
接著我要說另外一件事,雖然會來到it邦的……應該都是已經學會程式,並且能力非常厲害(我除外)的人,但是我寫這個的時候想的是 能不能讓完全不懂程式碼的人使用呢?
那要怎麼將程式碼打包成exe檔呢?
就要使用pyinstaller啦~首先要pip install pyinstaller
等它安裝完就直接又在cmd下pyinstaller -F rsa.py -w
他就會生成你想要的exe檔囉~
pyinstaller -F rsa.py 是將程式打包成exe,rsa.py是我們剛剛計算rsa的檔案名。
-w則可以將背景執行的console不顯示~
^w^來看看影片吧~
那明天就到了我們的MySQL和Python連接囉~
是說雖然我沒上過資料庫程式設計只上過概論(而且還完全不知道發生什麼的過了XD)但是實際操作後可能是因為用的很粗淺~感覺有點有趣XD
終於碰了自己一直規避的問題~感謝鐵人賽~
事隔四天_
我今天才發現原來……別人已經幫我們寫好RSA。
所以讓我們來修整我們的公私鑰生成器吧。
from tkinter import Tk, Label, Entry, Button,StringVar
import tkinter.font as tkFont
import rsa
mainWin = Tk()
mainWin.title("RSA生成器")
mainWin.geometry("250x200")
ft = tkFont.Font(family='Fixdsys', size=20, weight=tkFont.BOLD)
firstNumLabel = Label(mainWin, text="公鑰",font=ft)
secondNumLabel = Label(mainWin, text="私鑰",font=ft)
public_key=StringVar()
private_key=StringVar()
firstNum = Entry(mainWin, text=public_key)
secondNum = Entry(mainWin, text=private_key)
def cal():
(pubkey, privkey) = rsa.newkeys(1024)
public_key.set(pubkey)
private_key.set(privkey)
firstNumLabel.grid(row=0,column=0)
firstNum.grid(row=0,column=2)
secondNumLabel.grid(row=1,column=0)
secondNum.grid(row=1,column=2)
Btn.place(x=120,y=120)
mainWin.mainloop()
我覺得以我目前的狀態就是……啞口無言
想講話,可是又悲傷QAQ 蠢的一批
自己寫個毛線啊寫!