Python 2.7
IDE Pycharm 5.0.3
PyMySQL 0.7.6
MySQL 5.7
MySQL Workbench 6.3
至于MySQL和Python如何聯(lián)調(diào)使用請看上期Python與MySQL聯(lián)動實例一兩則
我要填以前挖過的坑了,用戶存儲加密驗證系統(tǒng)beta上線
填坑&目的
這坑是Python用戶存儲加密及登錄驗證系統(tǒng)(乞丐版)挖的,當(dāng)時還不會使用數(shù)據(jù)庫,現(xiàn)在學(xué)到了,不填坑不太好是不是?
應(yīng)用場景
如果數(shù)據(jù)庫是暫存在第三方,而且存入的數(shù)據(jù)又不想讓第三方數(shù)據(jù)庫管理員看到,消息涉及隱私,只有自己可見,那么怎么辦呢,我自己設(shè)計了一套用戶加密驗證系統(tǒng),對登錄密碼進(jìn)行MD5/SHA1可選加密,對明文進(jìn)行自定義的加密算法進(jìn)行加密存儲。短時間內(nèi)無法破解(私以為)
特點
用戶加密存儲系統(tǒng)--用于托管第三方數(shù)據(jù)庫,內(nèi)容進(jìn)行加密后存儲,沒有秘鑰無法破解
1.用戶存儲,登錄,查看,刪除操作,存儲在數(shù)據(jù)庫中
2.用戶密碼加密存儲,密碼加密方式可選,目前只可選MD5和SHA1,用戶存儲內(nèi)容加密存儲,加密方式自定義
3.自定義(我自己定義了一個加密解密函數(shù))加密序列,拿到內(nèi)容沒有序列無法解密(自以為)
4.可更改用戶密碼,更改自定義KEY值,更改加密存儲內(nèi)容
5.支持任何位數(shù)和形式設(shè)置密碼,甚至可以設(shè)置成中文!但是請注意,最好是雜亂無序字母夾雜的,不然被破解第一層密碼后,KEY值可能會暴露!
實現(xiàn)流程框架
這尼瑪我圖用Visio花了一個多小時。。。。可能我畢設(shè)都沒那么較真的畫圖。。。。
其實上面流程圖的最左邊如果新建用戶和數(shù)據(jù)庫中用戶重名,則有兩個選擇,一個是重新命名,另一個就是對原來用戶名進(jìn)行修改密碼,線有點多,太亂了連過去,所以這里省略了,實現(xiàn)效果請看下面的IDE交互章節(jié)。
好了,整體的思路框架就是這樣,當(dāng)然一開始我沒有想那么多,只是做著做著,想著不斷增加功能,更加完善性考慮,才會加入那么多選擇項的,因為自己設(shè)計的,所以,難免存在瑕疵,也沒有參考實際大的加密工程中如何處理,下次去看看。
實現(xiàn)代碼
這里我就不貼詳細(xì)代碼了,太長了,估計三四百行把,我上傳資源了源碼(帶注釋)+exe(exe由于打包軟件限制只能用于英文字符輸入)+readme(請先閱讀),不需要積分可以下載,點擊這里源碼進(jìn)行下載
這里只是貼上自己寫的加密算法部分。見諒!
#自定義加密、解密算法子函數(shù)。結(jié)合base64
def encrypt(key,content): # key:密鑰,content:明文
s1 = base64.encodestring(str(content)) #將內(nèi)容進(jìn)行base64加密
len1 = len(key) % 7 #取余數(shù)
len1_list = list_key[len1] #取余數(shù)對應(yīng)list_key中偽碼
mix_first = str(key)+s1 #將key轉(zhuǎn)化為字符串后拼接第一次加密的內(nèi)容
mix = len1_list+base64.encodestring(mix_first) #對拼接后字符串再進(jìn)行加密,再加個偽碼
return mix #存入數(shù)據(jù)庫中,不能被反解
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值對應(yīng)了
s2_end = base64.decodestring(s2_first[len(key):])#反解出去掉前綴后的真實內(nèi)容的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!"
解釋就在上面的注釋上了,這里說一下實現(xiàn)效果,存入數(shù)據(jù)庫中形式應(yīng)該是這樣的
對于自己的加密算法:自己嘗試寫,肯定會有紕漏的地方,如果以后有機(jī)會,可以學(xué)一下密碼學(xué),自己接觸的到底還是太少了,只是添加了偽碼表,然后兩次base64加密,當(dāng)然,數(shù)據(jù)庫中內(nèi)容直接拿來base64解碼肯定是不會成功的。
登錄密碼是用MD5/SHA1進(jìn)行加密的,而第二層,登陸之后,可以自己選擇KEY值,對輸入的明文進(jìn)行加密,如果沒有我的偽字典和KEY應(yīng)該是不能反解出加密的內(nèi)容的,所以對于數(shù)據(jù)庫管理員來說,根本不能解密存入數(shù)據(jù)庫中的內(nèi)容,對于有特殊需求的記錄也好,項目也好,我想應(yīng)該有應(yīng)用的地方。
交互效果
這里顯示的是整個IDE交互界面,如何處理這些;
0.進(jìn)行新用戶注冊(可以選擇不設(shè)置明文默認(rèn)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.進(jìn)行設(shè)置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!#
#############################################
以下是默認(rèn)KEY與明文設(shè)置,選擇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步中,如果沒有自己設(shè)置KEY等,會有個默認(rèn)值進(jìn)行存儲)
以下為自己設(shè)置了KEY和明文(沒有設(shè)置時候,則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
更加詳細(xì)的請自己測試使用。代碼和上述流程圖保持一致。
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.解決方案,多進(jìn)行try/except使用拋出錯誤,定位錯誤,常用輸出語句進(jìn)行和預(yù)期值之間的排錯,如下,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"))
運(yùn)行后
('202cb962ac59075b964b07152d234b70',)
<type 'tuple'>
40bd001563085fc35165329ea1ff5c5ecbdbbeef
<type 'str'>
知道所出現(xiàn)的形式之后,對癥下藥就可以了!
2.對數(shù)據(jù)庫進(jìn)行插入,刪除,更新操作,數(shù)據(jù)庫內(nèi)容不改變問題
2.解決方案,沒有進(jìn)行事務(wù)提交!
比如,我實現(xiàn)添加操作,最后需要添加語句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()提交事物,做出改變后必須提交事務(wù),不然不能更新
3.數(shù)據(jù)庫出現(xiàn)Lock wait timeout exceeded錯誤,原因是如圖
3.解決方案;這里應(yīng)該運(yùn)行時候斷開以前運(yùn)行的程序,這點我做的不好,調(diào)試的時候,以前的程序還在運(yùn)行,全部斷開連接,只要一個運(yùn)行就行
4.結(jié)構(gòu)功能問題
4.需要實踐積累,怎樣實現(xiàn)目的,產(chǎn)生比較清晰的架構(gòu),子函數(shù)應(yīng)該怎么寫,才能最大程度的調(diào)用,這些我都比較弱,需要不斷的進(jìn)行學(xué)習(xí)和測試,我的框架結(jié)構(gòu)也是改了很多次,都是進(jìn)行測試之后慢慢修改成型的,考慮到了幾乎所有的操作需求,你能信當(dāng)時我只是想弄個加密寫入和讀取的玩意就行了么,最后還是寫成比較完善的一個小項目了,所以,這個問題,只有不斷練習(xí)把,不過下次我會先擬構(gòu)好一個流程圖框架再寫。
What's new?Man
從最初涉及到全部功能實現(xiàn),寫函數(shù)的時間大概只占了百分之三十,其余時間都在進(jìn)行排錯調(diào)試,因為功能的繁多,并不知道哪里會出錯,可能功能和功能之間銜接,可能大的分選項,退出到幾級菜單,這些問題我?guī)缀趺總€都遇到過,最后一一解決,感覺很棒!以后分塊寫模塊調(diào)試,還是很重要的,還有就是,模塊包裹的成分多少我還沒把握好,最高效的調(diào)用模塊才是個好模塊呢!
吐槽
沒有兩個顯示屏寫東西真的太費勁了!代碼拉過來拉過去的,懷念實驗室的側(cè)放顯示器了。。。就像這樣。
so see you guys,have a good day!
致謝
Python網(wǎng)絡(luò)數(shù)據(jù)采集[Ryan Mitchell著][人民郵電出版社]
@Mrlevo520--Python用戶存儲加密及登錄驗證系統(tǒng)(乞丐版)
在線轉(zhuǎn)換工具--將代碼以BASE64方式加密、解密
@Mrlevo520--Python與MySQL聯(lián)動實例一兩則
@li_feibo--關(guān)于Lock wait timeout exceeded; try restarting transaction