一、前言:
目的:完成已有python圖像處理工具的注冊(cè)功能
功能:用戶運(yùn)行程序后,通過(guò)文件自動(dòng)檢測(cè)認(rèn)證狀態(tài),如果未經(jīng)認(rèn)證,就需要注冊(cè)。注冊(cè)過(guò)程是用戶將程序運(yùn)行后顯示的機(jī)器碼(C盤(pán)的卷序號(hào))發(fā)回給管理員,管理員對(duì)機(jī)器碼加密后生成加密文件或字符串返回給用戶。每次啟動(dòng)程序,在有注冊(cè)文件的情況下,程序就會(huì)通過(guò)DES和base64解碼,并與此刻獲取到的C盤(pán)卷序列號(hào)比對(duì),如果一致則運(yùn)行主程序。如果注冊(cè)文件解碼后與卷序號(hào)不一致,就要提醒用戶輸入注冊(cè)碼,如果對(duì)新輸入的解碼后和重新獲取的機(jī)器碼一致,則通過(guò)認(rèn)證,生成新的注冊(cè)文件后進(jìn)入主程序。
庫(kù)和組件:
1、pyDes用于加密解密
2、base64,用于pyDes加密解密后的二次加密解密
3、win32api,用于獲取C盤(pán)卷序列號(hào)
4、pyinstaller,打包
參考:
1、pyDes庫(kù) 實(shí)現(xiàn)python的des加密
http://www.mamicode.com/info-detail-508384.html
http://twhiteman.netfirms.com/des.html
2、win32api.GetVolumeInformation
http://timgolden.me.uk/pywin32-docs/win32api__GetVolumeInformation_meth.html
3、pyinstaller打包文件說(shuō)明
http://pythonhosted.org/PyInstaller/spec-files.html#using-spec-files
二、實(shí)現(xiàn)
#coding:utf8#register.py#功能說(shuō)明:用戶運(yùn)行程序后,自動(dòng)檢測(cè)認(rèn)證狀態(tài),如果未經(jīng)認(rèn)證,就需要注冊(cè)。注冊(cè)過(guò)程是用戶將程序運(yùn)行后顯示的機(jī)器碼(卷序號(hào))發(fā)回給管理員,管理員通過(guò)加密后生成加密文件或字符串給回用戶。#每次登錄,在有注冊(cè)文件或者注冊(cè)碼的情況下,軟件就會(huì)通過(guò)DES和base64解碼,如果解碼后和重新獲取的機(jī)器碼一致,則通過(guò)認(rèn)證,進(jìn)入主程序。import base64import win32apifrom pyDes import *#from binascii import a2b_hex #如果需要用二進(jìn)制編碼保存注冊(cè)碼和注冊(cè)文件可以使用binascii轉(zhuǎn)換class register:def __init__(self):self.Des_Key = "BHC#@*UM" # Keyself.Des_IV = "/x22/x33/x35/x81/xBC/x38/x5A/xE7" # 自定IV向量#獲取C盤(pán)卷序列號(hào)#使用C盤(pán)卷序列號(hào)的優(yōu)點(diǎn)是長(zhǎng)度短,方便操作,比如1513085707,但是對(duì)C盤(pán)進(jìn)行格式化或重裝電腦等操作會(huì)影響C盤(pán)卷序列號(hào)。#win32api.GetVolumeInformation(Volume Name, Volume Serial Number, Maximum Component Length of a file name, Sys Flags, File System Name)#return('', 1513085707, 255, 65470719, 'NTFS'),volume serial number is 1513085707.def getCVolumeSerialNumber(self):CVolumeSerialNumber=win32api.GetVolumeInformation("C://")[1]#print chardet.detect(str(CVolumeSerialNumber))#print CVolumeSerialNumberif CVolumeSerialNumber:return str(CVolumeSerialNumber) #number is long type,has to be changed to str for comparing to content after.else:return 0#使用DES加base64的形式加密#考慮過(guò)使用M2Crypto和rsa,但是都因?yàn)樵趙indows環(huán)境中糟糕的安裝配置過(guò)程而放棄def DesEncrypt(self,str):k = des(self.Des_Key, CBC, self.Des_IV, pad=None, padmode=PAD_PKCS5)EncryptStr = k.encrypt(str)#EncryptStr = binascii.unhexlify(k.encrypt(str))return base64.b64encode(EncryptStr) #轉(zhuǎn)base64編碼返回#des解碼def DesDecrypt(self,str):k = des(self.Des_Key, CBC, self.Des_IV, pad=None, padmode=PAD_PKCS5)DecryptStr = k.decrypt(str)#DecryptStr = a2b_hex(k.decrypt(str))print DecryptStrreturn DecryptStr#獲取注冊(cè)碼,驗(yàn)證成功后生成注冊(cè)文件def regist(self):key = raw_input('please input your register code: ')#由于輸入類(lèi)似“12”這種不符合base64規(guī)則的字符串會(huì)引起異常,所以需要增加輸入判斷#while keyif key:content = self.getCVolumeSerialNumber() //number has been changed to str type after use str() #print chardet.detect(content)#print type(content)#print content#type(key_decrypted) is strkey_decrypted=str(self.DesDecrypt(base64.b64decode(key)))#print chardet.detect(key_decrypted)#print key_decrypted#type(key_decrypted) is strif content!=0 and key_decrypted!=0:if content != key_decrypted:print "wrong register code, please check and input your register code again:"self.regist()elif content==key_decrypted:print "register succeed."#讀寫(xiě)文件要加判斷with open('./register','w') as f:f.write(key)f.close()return Trueelse:return Falseelse:return Falseelse:self.regist()return Falsedef checkAuthored(self):content=self.getCVolumeSerialNumber()checkAuthoredResult = 0#讀寫(xiě)文件要加判斷try:f=open('./register','r')if f:key=f.read()if key:key_decrypted=self.DesDecrypt(base64.b64decode(key))if key_decrypted:if key_decrypted == content:checkAuthoredResult = 1else:checkAuthoredResult = -1else:checkAuthoredResult = -2else:checkAuthoredResult = -3else:self.regist()except IOError:print IOErrorprint checkAuthoredResultreturn checkAuthoredResultif __name__ == '__main__':reg=register()reg.regist()三、備注
1、使用C盤(pán)卷序列號(hào)而不是硬盤(pán)號(hào)的原因是:位數(shù)短,方便操作。
但是使用硬盤(pán)號(hào)才是更安全的做法,因?yàn)橛脖P(pán)號(hào)不會(huì)因重裝系統(tǒng)、格式化C盤(pán)或修改C盤(pán)序號(hào)而改變。
#CVolumeSerialNumber: 1513085707#after encryption: ro5RVXZoP0KmnogYDeepUg==#the HardDiskNumber: 32535332584e4741343536393237204620202020#after encryption: MzI1MzUzMzI1ODRlNDc0MTM0MzUzNjM5MzIzNzIwNDYyMDIwMjAyMA==
2、除了win32api,wmi也可以用來(lái)獲取系統(tǒng)信息(比如硬盤(pán)號(hào)),獲取完整硬盤(pán)號(hào)的過(guò)程如下:
#雖然使用wmi可以獲取磁盤(pán)序列號(hào),可是磁盤(pán)序列號(hào)是3253533258**************3237204620202020,加密后太長(zhǎng),不方便操作,所以棄置import wmidef getHardDiskNumber(self):c = wmi.WMI()for physical_disk in c.Win32_DiskDrive():return physical_disk.SerialNumber
https://pypi.python.org/pypi/WMI/
3、chardet可以用來(lái)檢驗(yàn)字符串的編碼類(lèi)型,可以用在檢測(cè)字符串相等上
chardet.detect(str)
4、還存在一些邏輯上的漏洞,比如讀寫(xiě)文件時(shí)對(duì)文件是否存在的判斷,讀取方式的選擇等
5、register.py,供main函數(shù)或其他需要獲取認(rèn)證狀態(tài)的函數(shù)調(diào)用。
main函數(shù)中使用register類(lèi)的過(guò)程是:
創(chuàng)建logIn函數(shù)用于獲取認(rèn)證結(jié)果-》如果認(rèn)證結(jié)果為假則重新調(diào)用register類(lèi)的regist函數(shù),提醒用戶輸入注冊(cè)碼,只有成功輸入了注冊(cè)碼才能創(chuàng)建新的注冊(cè)文件-》如果認(rèn)證結(jié)果為真則直接啟動(dòng)主程序。
6、管理員還應(yīng)該有一個(gè)encryption.py,用于使用des+base64算法對(duì)用戶發(fā)過(guò)來(lái)的C盤(pán)卷序列號(hào)進(jìn)行加密,加密以后生成字符串或注冊(cè)文件,再返還給用戶,不再贅述。
以上所述是小編給大家介紹的基于python腳本實(shí)現(xiàn)軟件的注冊(cè)功能(機(jī)器碼+注冊(cè)碼機(jī)制),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!
新聞熱點(diǎn)
疑難解答
圖片精選