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!