久久午夜无码,国产中文资源,Chinese熟女熟妇2乱2,高清五码d一区

win10密鑰生成器(為你的python程序上鎖軟件序列號生成器)

win10密鑰生成器(為你的python程序上鎖軟件序列號生成器)

圣芳林 2025-04-14 科技 15 次瀏覽 0個評論
序列號

很多同學(xué)可能開發(fā)了非常多的程序了,并且進行了 exe 的打包,可是由于沒有使用序列號,程序被無限復(fù)制,導(dǎo)致收益下降。

接下來我們來自己實現(xiàn)序列號的生成及使用,通過本文的學(xué)習(xí),希望能夠幫助到你!

本文適合 windows 系統(tǒng),linux 系統(tǒng)原理相通,但代碼有所不同。

安裝庫pip install wmipip install pycryptodome結(jié)構(gòu)流程圖為你的python程序上鎖:軟件序列號生成器

結(jié)構(gòu)圖

我們首先要通過 硬件信息、UUID和時間戳 來生成一個 協(xié)議文件,再通過非對稱加密 RSA 生成公鑰和私鑰。

當(dāng)我們給客戶程序的時候,會附帶一個 私鑰程序啟動時會判斷是否存在 協(xié)議文件 ,如果沒有 協(xié)議文件 將會生成一個 序列號,客戶需要把序列號發(fā)送給管理員管理員獲取 序列號,使用 公鑰 進行加密生成 協(xié)議文件,將其發(fā)送給客戶客戶將 協(xié)議文件 放在相應(yīng)位置,程序使用 私鑰 進行解密,與相應(yīng)的 序列號 進行對比協(xié)議文件 解密成功,通過 協(xié)議文件序列號 中的時間戳信息判斷是否過期當(dāng)時間戳未過期,則運行程序,反之無法啟動,提示 序列號過期結(jié)構(gòu)代碼1. 生成RSA公鑰與私鑰文件from Crypto import Randomfrom Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5import osimport datetimeimport base64CURRENT_FOLDER_PATH = os.path.dirname(os.path.abspath(__file__))def make_rsa_key(length=1024): """ 生成公鑰和私鑰 :return: """ # 偽隨機數(shù)生成器 random_gen = Random.new().read # 生成秘鑰對實例對象:1024是秘鑰的長度 rsa = RSA.generate(length, random_gen) private_pem = rsa.exportKey() public_pem = rsa.publickey().exportKey() return private_pem, public_pemdef rsa_encrypt(pub_key, content, length=128): """ rsa數(shù)據(jù)加密,單次加密串的長度最大為 (key_size/8)-11 1024bit的證書用100, 2048bit的證書用 200 :param pub_key: :param content: :param length: :return: """ pub_key = RSA.importKey(pub_key.decode()) cipher = PKCS1_v1_5.new(pub_key) content = content.encode() res = [] for i in range(0, len(content), length): res.append(cipher.encrypt(content[i: i + length])) return base64.b64encode(base64.b64encode(b''.join(res)))def rsa_decrypt(pri_key, encrypt_txt, length=128): """ rsa信息解密 1024bit的證書用128,2048bit證書用256位 :param pri_key: :param encrypt_txt: :param length: :return: """ try: encrypt_txt = base64.b64decode(encrypt_txt) encrypt_txt = base64.b64decode(encrypt_txt.decode()) pri_obj = RSA.importKey(pri_key) pri_obj = PKCS1_v1_5.new(pri_obj) res = [] for i in range(0, len(encrypt_txt), length): res.append(pri_obj.decrypt(encrypt_txt[i:i + length], '')) return b''.join(res) except Exception as e: return Nonedef rsa_file_generator(pri_path, pub_path, length=1024): """ 生成公私鑰文件 :param pri_path: 私鑰文件地址 :param pub_path: 公鑰文件地址 :return: """ pri_key, pub_key = make_rsa_key(length) with open(pri_path, 'wb') as f: f.write(pri_key) with open(pub_path, 'wb') as f: f.write(pub_key) return pri_key, pub_keydef get_or_make_rsa(refresh=False): """ 生成或獲取公私鑰內(nèi)容 :return: """ folder_path = os.path.join(CURRENT_FOLDER_PATH, 'pem') if not os.path.exists(folder_path): os.makedirs(folder_path) file_list = os.listdir(folder_path) now = datetime.datetime.now() now_str = now.strftime('%Y%m%d%H%M%S') new_pri_path = os.path.join(folder_path, f'{now_str}_private.pem') new_pub_path = os.path.join(folder_path, f'{now_str}_public.pem') # 公鑰和私鑰文件不存在 if len(file_list) == 0: pri_key, pub_key = rsa_file_generator( new_pri_path, new_pub_path, 1024 ) else: pri_path = '' pub_path = '' for file in file_list: if file.endswith('private.pem'): pri_path = os.path.join(folder_path, file) elif file.endswith('public.pem'): pub_path = os.path.join(folder_path, file) if not pri_path or not pub_path: pri_key, pub_key = rsa_file_generator( new_pri_path, new_pub_path, 1024 ) else: # 手動更新私鑰 if refresh: pri_key, pub_key = rsa_file_generator( new_pri_path, new_pub_path, 1024 ) os.remove(pri_path) os.remove(pub_path) else: with open(pri_path, 'rb') as f: pri_key = f.read() with open(pub_path, 'rb') as f: pub_key = f.read() return pri_key, pub_key

使用 get_or_make_rsa() 方法即可獲取公鑰與私鑰,程序會生成一個 pem 文件夾保存相應(yīng)的公鑰和私鑰。

如果需要更新公鑰與私鑰,只要調(diào)用 get_or_make_rsa() 方法時,傳入 refresh 的值為 True 即可。

CURRENT_FOLDER_PATH 全局變量保存的是當(dāng)前程序的絕對路徑,就算是打包后的 exe 也可以正確獲取。

2. 序列號生成import uuidimport wmiimport hashlibfrom itertools import zip_longestdef get_license_txt(): c = wmi.WMI() # 獲取第一個硬盤的序列號 disk_number = '' for physical_disk in c.Win32_DiskDrive(): disk_number = physical_disk.SerialNumber.strip() break # 獲取第一個CPU的序列號 cpu_number = '' for cpu in c.Win32_Processor(): cpu_number = cpu.ProcessorId.strip() break # 獲取第一個BIOS的序列號 bios_number = '' for bios in c.Win32_BIOS(): bios_number = bios.SerialNumber.strip() break uid = get_a_guid() paired = zip_longest(disk_number, cpu_number, bios_number, uid, fillvalue='_') result = '|'.join([''.join(pair) for pair in paired]) content = hashlib.md5(result.encode()).hexdigest().upper() return f'{content}=={uid}'

我們使用了一個相對復(fù)雜的方式將 硬盤、cpu、BIOS 的序列號與一個 UUID 進行組合,竟將其進行 md5 加密,最后將這個 加密結(jié)果 與 UUID 明文組合在一起作為一個 完整的軟件序列號。

現(xiàn)在,客戶將在程序啟動時拿到這個 軟件序列號 ,再將這個軟件序列號發(fā)送給管理員進行加密即可。

加密方法將使用之前的 rsa_encrypt() 方法。

3. 加密軟件序列號def make_license_key_file(license_txt='', days=365): ''' 創(chuàng)建協(xié)議文件 :param license_txt: 軟件序列號 :param days: 有效天數(shù) :return: ''' pri_key, pub_key = get_or_make_rsa() s_list = license_txt.split('==') if len(s_list) != 2: return None uid = s_list[1] timestamp = int(datetime.datetime.now().timestamp()) + days * 86400 new_license_text = f'{license_txt}=={timestamp}' res = rsa_encrypt(pub_key, new_license_text).decode() folder_path = os.path.join(CURRENT_FOLDER_PATH, 'key') if not os.path.exists(folder_path): os.makedirs(folder_path) file_path = os.path.join(folder_path, f'{uid}.key') with open(file_path, 'wb') as f: f.write(res.encode()) return file_path

以當(dāng)前時間戳為基準(zhǔn)添加有效天數(shù),然后將客戶發(fā)送過來的序列號再進行一次組合,最后通過 公鑰 進行加密,生成一個 協(xié)議文件 發(fā)送給客戶。

4. 驗證協(xié)議文件def auth_license(key_file_path='', pem_file_path=''): c = wmi.WMI() disk_number = '' for physical_disk in c.Win32_DiskDrive(): disk_number = physical_disk.SerialNumber.strip() break cpu_number = '' for cpu in c.Win32_Processor(): cpu_number = cpu.ProcessorId.strip() break bios_number = '' for bios in c.Win32_BIOS(): bios_number = bios.SerialNumber.strip() break # 協(xié)議文件不存在,無法通過 if not os.path.exists(key_file_path): return False # 私鑰文件不存在,無法通過 if not os.path.exists(pem_file_path): return False # 讀取協(xié)議文件內(nèi)容 with open(key_file_path, 'rb') as f: key_res = f.read().decode() # 讀取私鑰內(nèi)容 with open(pem_file_path, 'rb') as f: pem_res = f.read().decode() res = rsa_decrypt(pem_res, key_res).decode() # 解密失敗,無法通過 if not res: return False s_list = res.split('==') # 沒有兩個等號的內(nèi)容,無法通過 if len(s_list) != 3: return False uid = s_list[1] paired = zip_longest(disk_number, cpu_number, bios_number, uid, fillvalue='_') result = '|'.join([''.join(pair) for pair in paired]) content = hashlib.md5(result.encode()).hexdigest().upper() # 序列號不一致,無法通過 if content != s_list[0]: return False try: timestamp = int(s_list[2]) except Exception as e: # 無法變?yōu)闀r間戳,無法通過 return False now_timestamp = int(datetime.datetime.now().timestamp()) # 在有效時間內(nèi),通過 if now_timestamp <= timestamp: return True return False

這個驗證過程其實就是再次進行一次 序列號 組合,來判斷是否與 協(xié)議文件 一致,其后還需判斷是否在有效期內(nèi)。

結(jié)尾

我相信如果認(rèn)真看完文章的朋友已經(jīng)可以實現(xiàn)自己的序列號生成器了,不過在此之前我需要申明這個文章的代碼還不是完整版,這里提幾個優(yōu)化點:

定時驗證:定時判斷是否超過有效期,防止客戶程序未關(guān)閉,就算超過有效期還能繼續(xù)使用 打包為加密模塊:當(dāng)前代碼為明文代碼,由于 python 為解釋器語言,如果不加密打包,很容易被破解規(guī)則 添加可視化窗口:為了方便使用,可以將程序設(shè)計為可視化窗口模式,最簡單的方式使用 TK 創(chuàng)建

當(dāng)然,如果你不想自己寫,推薦可以直接使用 pyarmor ,這也是國人開發(fā)的一個加密庫,包含加密、有效期、許可證。

如果這篇文章對你有幫助,點個贊讓我知道哦!

轉(zhuǎn)載請注明來自夕逆IT,本文標(biāo)題:《win10密鑰生成器(為你的python程序上鎖軟件序列號生成器)》

每一天,每一秒,你所做的決定都會改變你的人生!

發(fā)表評論

快捷回復(fù):

評論列表 (暫無評論,15人圍觀)參與討論

還沒有評論,來說兩句吧...

色秘 在线观看| 久久人妻无码一区| 99久久超碰中文字幕伊人| 亚洲一区国产精品老牛| 国产无遮挡18禁无码免费| 99久久人妻无码精品系列九色| 四虎精品免费在线观看| 久久起碰| 亚洲成a人片77777kkkk| 视色视色中文字幕网站| 国产日本欧美一区二区bt下载| 亚州久中文字幕| 麻豆91精品91久久久| 久久国产成人美女| 亚洲二区在线播放| 亚洲精品xxxxx| 狠狠躁夜夜躁人人爽天天不| 国产成_人_综合_亚洲_| 国自产拍偷拍精品久久| 超碰窝窝福利导肮| 日韩激情视频久久一区| AV无码播放一级毛片免费野外| 九九精品免视频国产成人| 国产精品久久久影院| 久久免费国产小电影| 国产精品亚洲国产三区| 精品麻豆亚洲欧美| 丁香六月激情蜜桃| 91久久美女| 国产免费A∨片在线观看| 日韩无在线| 国产乱老熟| 国产成人AV男人的天堂| 免费无码va一区二区三| 得荣县| 亚洲五月综合网| 欧洲精品人妻无码久久久| 免费看AV在线网站网址| 亚洲精品综合自拍偷拍| 久久久老熟女一区二区三区| 亚洲无码午夜在线免费观看|