1. 程式人生 > >Python+MySQL使用者加密儲存驗證系統(進階)

Python+MySQL使用者加密儲存驗證系統(進階)

Python 2.7
IDE Pycharm 5.0.3
PyMySQL 0.7.6
MySQL 5.7
MySQL Workbench 6.3

我要填以前挖過的坑了,使用者儲存加密驗證系統beta上線

填坑&目的

應用場景

如果資料庫是暫存在第三方,而且存入的資料又不想讓第三方資料庫管理員看到,訊息涉及隱私,只有自己可見,那麼怎麼辦呢,我自己設計了一套使用者加密驗證系統,對登入密碼進行MD5/SHA1可選加密,對明文進行自定義的加密演算法進行加密儲存。短時間內無法破解(私以為)

特點

使用者加密儲存系統–用於託管第三方資料庫,內容進行加密後儲存,沒有祕鑰無法破解

1.使用者儲存,登入,檢視,刪除操作,儲存在資料庫中
2.使用者密碼加密儲存,密碼加密方式可選,目前只可選MD5和SHA1,使用者儲存內容加密儲存,加密方式自定義
3.自定義(我自己定義了一個加密解密函式)加密序列,拿到內容沒有序列無法解密(自以為)
4.可更改使用者密碼,更改自定義KEY值,更改加密儲存內容
5.支援任何位數和形式設定密碼,甚至可以設定成中文!但是請注意,最好是雜亂無序字母夾雜的,不然被破解第一層密碼後,KEY值可能會暴露!

實現流程框架

這尼瑪我圖用Visio花了一個多小時。。。。可能我畢設都沒那麼較真的畫圖。。。。

這裡寫圖片描述

其實上面流程圖的最左邊如果新建使用者和資料庫中使用者重名,則有兩個選擇,一個是重新命名,另一個就是對原來使用者名稱進行修改密碼,線有點多,太亂了連過去,所以這裡省略了,實現效果請看下面的IDE互動章節。

好了,整體的思路框架就是這樣,當然一開始我沒有想那麼多,只是做著做著,想著不斷增加功能,更加完善性考慮,才會加入那麼多選擇項的,因為自己設計的,所以,難免存在瑕疵,也沒有參考實際大的加密工程中如何處理,下次去看看。

實現程式碼

這裡我就不貼詳細程式碼了,太長了,估計三四百行把,我上傳資源了原始碼(帶註釋)+exe(exe由於打包軟體限制只能用於英文字元輸入)+readme(請先閱讀),不需要積分可以下載,點選這裡原始碼進行下載
這裡只是貼上自己寫的加密演算法部分。見諒!

#自定義加密、解密演算法子函式。結合base64
def encrypt(key,content): # key:金鑰,content:明文
s1 = base64.encodestring(str(content)) #將內容進行base64加密 len1 = len(key) % 7 #取餘數 len1_list = list_key[len1] #取餘數對應list_key中偽碼 mix_first = str(key)+s1 #將key轉化為字串後拼接第一次加密的內容 mix = len1_list+base64.encodestring(mix_first) #對拼接後字串再進行加密,再加個偽碼 return mix #存入資料庫中,不能被反解 def decrypt(key,mix): # key:金鑰,content:密文 len2 = len(key) % 7 len2_findlist = list_key[len2] if len2_findlist==mix[0]: #先確定偽碼 s2_first = base64.decodestring(mix[1:])#反解出第一次的base64編碼 s2_second = s2_first[0:len(key)] #獲取第一次解出字首是否為key if s2_second==str(key):#key值對應了 s2_end = base64.decodestring(s2_first[len(key):])#反解出去掉字首後的真實內容的64位編碼 print '-------------------------------Validation Succeed!-------------------------------' return s2_end else: print "Warning!Validation Failed!Can't Get Secret Words!" else: print "Warning!Validation Failed!Can't Get Secret Words!"

解釋就在上面的註釋上了,這裡說一下實現效果,存入資料庫中形式應該是這樣的
這裡寫圖片描述

對於自己的加密演算法:自己嘗試寫,肯定會有紕漏的地方,如果以後有機會,可以學一下密碼學,自己接觸的到底還是太少了,只是添加了偽碼錶,然後兩次base64加密,當然,資料庫中內容直接拿來base64解碼肯定是不會成功的。

登入密碼是用MD5/SHA1進行加密的,而第二層,登陸之後,可以自己選擇KEY值,對輸入的明文進行加密,如果沒有我的偽字典和KEY應該是不能反解出加密的內容的,所以對於資料庫管理員來說,根本不能解密存入資料庫中的內容,對於有特殊需求的記錄也好,專案也好,我想應該有應用的地方。

互動效果

這裡顯示的是整個IDE互動介面,如何處理這些;

0.進行新使用者註冊(可以選擇不設定明文預設KEY為123456)

-------------------------------Mode Choice-------------------------------------
Store&Encrypt-1     Login&View&Update&Delete-2    Quit System-3    Clear Database-4
Select Mode:1
-------------------------------Store&Encrypt-------------------------------
New User:k3
Set Password:k3
-------------------------------Password Encrypt Algorithm-------------------------------------
MD5-1   SHA1-2
Select Algorithm:1

1.進行設定KEY和明文加密

-------------------------------What's Next?-------------------------------------
Store Encrypt Plaintext-1    Maybe Next Time-2
Your Choice:1
Please Design Your KEY:k4
Plaintext:k4'secret
#############################################
#SHA1-Password&Plaintext Encryption Succeed!#
#############################################

以下是預設KEY與明文設定,選擇2即可

-------------------------------What's Next?-------------------------------------
Store Encrypt Plaintext-1    Maybe Next Time-2
Your Choice:2
Default KEY '123456'
Default Plaintext 'Default Storage'
############################################
#MD5-Password&Plaintext Encryption Succeed!#
############################################

2.檢視加密明文
(第0步中,如果沒有自己設定KEY等,會有個預設值進行儲存)

以下為自己設定了KEY和明文(沒有設定時候,則KEY為123456),檢視明文

-------------------------------k4:What's Next?-------------------------------
Update Plaintext-1    View Plaintext-2    Update Password-3    Update KEY-4    Log out-5    Delete User-6
Your Choice: 2
KEY:k4
-------------------------------Validation Succeed!-------------------------------
Secret Words:k4'secret

更加詳細的請自己測試使用。程式碼和上述流程圖保持一致。

3.遇到新使用者重名,解決途徑,修改密碼或者更換新名字

-------------------------------Mode Choice-------------------------------------
Store&Encrypt-1     Login&View&Update&Delete-2    Quit System-3    Clear Database-4
Select Mode:1
-------------------------------Store&Encrypt-------------------------------
New User:k1
Warning!The Name Already Exist!
-------------------------------Make Your Choice-------------------------------------
Change Password-1    Create New User-2
Select Mode:2
New User:k2
Set Password:k3

4.更新登入密碼選擇,需要有以前密碼,才能修改

-------------------------------Welcome k1-------------------------------
-------------------------------k1:What's Next?-------------------------------
Update Plaintext-1    View Plaintext-2    Update Password-3    Update KEY-4    Log out-5    Delete User-6
Your Choice: 3
Please Enter Original Password:k1
Please Enter New Password:k2
##########################
#Update Password Succeed!#
##########################

5.更新KEY值

-------------------------------Welcome k1-------------------------------
-------------------------------k1:What's Next?-------------------------------
Update Plaintext-1    View Plaintext-2    Update Password-3    Update KEY-4    Log out-5    Delete User-6
Your Choice: 4
Please Enter Original KEY:k1
Please Enter New KEY:k2
-------------------------------Validation Succeed!-------------------------------
#####################
#Update KEY Succeed!#
#####################

6.更新明文


-------------------------------k4:What's Next?-------------------------------
Update Plaintext-1    View Plaintext-2    Update Password-3    Update KEY-4    Log out-5    Delete User-6
Your Choice: 1
KEY:k4
-------------------------------Validation Succeed!-------------------------------
Original Plaintext:k4'secret
New Plaintext:k4's secret2
###########################
#Update Plaintext Succeed!#
###########################

遇到的問題及解決方案

1.MD5/SHA1加密儲存時候的型別不同引起的錯誤。
1.解決方案,多進行try/except使用丟擲錯誤,定位錯誤,常用輸出語句進行和預期值之間的排錯,如下,md5加密後為元組形式,而sha1為str型別

import hashlib

#MD5和SHA1加密演算法
def md5(str1):
    md = hashlib.md5()
    md.update(str1)
    md_5=md.hexdigest()
    return md_5,

def sha1(str1):
    sh = hashlib.sha1()
    sh.update(str1)
    sha_1 = sh.hexdigest()
    return sha_1

print md5("123")
print type(md5("123"))
print sha1("123")
print type(sha1("123"))

執行後

('202cb962ac59075b964b07152d234b70',)
<type 'tuple'>
40bd001563085fc35165329ea1ff5c5ecbdbbeef
<type 'str'>

知道所出現的形式之後,對症下藥就可以了!

2.對資料庫進行插入,刪除,更新操作,資料庫內容不改變問題
2.解決方案,沒有進行事務提交!
比如,我實現新增操作,最後需要新增語句commit

cur.execute("insert into store(user_name,passwd,encrypt_words,encrypt_password) VALUES (%s,%s,%s,%s)",(user_name,passwd,encrypt_str,key_content))

cur.connection.commit()#commit()提交事物,做出改變後必須提交事務,不然不能更新

3.資料庫出現Lock wait timeout exceeded錯誤,原因是如圖

這裡寫圖片描述

3.解決方案;這裡應該執行時候斷開以前執行的程式,這點我做的不好,除錯的時候,以前的程式還在執行,全部斷開連線,只要一個執行就行

4.結構功能問題
4.需要實踐積累,怎樣實現目的,產生比較清晰的架構,子函式應該怎麼寫,才能最大程度的呼叫,這些我都比較弱,需要不斷的進行學習和測試,我的框架結構也是改了很多次,都是進行測試之後慢慢修改成型的,考慮到了幾乎所有的操作需求,你能信當時我只是想弄個加密寫入和讀取的玩意就行了麼,最後還是寫成比較完善的一個小專案了,所以,這個問題,只有不斷練習把,不過下次我會先擬構好一個流程圖框架再寫。

What’s new?Man

從最初涉及到全部功能實現,寫函式的時間大概只佔了百分之三十,其餘時間都在進行排錯除錯,因為功能的繁多,並不知道哪裡會出錯,可能功能和功能之間銜接,可能大的分選項,退出到幾級選單,這些問題我幾乎每個都遇到過,最後一一解決,感覺很棒!以後分塊寫模組除錯,還是很重要的,還有就是,模組包裹的成分多少我還沒把握好,最高效的呼叫模組才是個好模組呢!

吐槽

沒有兩個顯示屏寫東西真的太費勁了!程式碼拉過來拉過去的,懷念實驗室的側放顯示器了。。。就像這樣。
這裡寫圖片描述

so see you guys,have a good day!

致謝