久久午夜无码,日日射天天射五月丁香婷婷我来了 ,欧美黑人又长又粗在线视频,午夜天网站

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人圍觀)參與討論

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

欧美激情一区视频| 欧美视频在线观看激情一区二区| 自偷自偷自亚洲永久| 国产一区二区精品无码免费看| 日韩免费精品| 亚洲免费成人电演| 国产精品美女久久久久aⅴ国产馆| 国内超级无码在线视频| 911久久人人超碰超碰窝窝| 小91AV| 日本无遮无挡视频| 大日韩av综合| 亚洲一区男人| 国产又粗又猛又爽又黄男同| 无码电影在线观看| 精品美女国产一区| 久久91精品国产91久久| 国产老太一性一交一乱| 亚洲一区二区精品热| 日本不卡高字幕在线2019| 五月夜影院毛片| 国产亚洲停久久| 九九精品视频国产| 一本色道久久88亚洲精品| 男男色男喷网站| 日本一区二区三区在线网| 久久五月综合婷婷私| 日韩毛片区| 99精品欧美一区二区综合在线| 亚洲 图 综合| 噜噜噜操操操| 国产精品一区二三区三亚| 亚洲国产AⅤ精品| 亚洲A√天堂| 欧美九热天天| 美女日比的全红的| 五月丁香激情四射啊| 欧美日本中文二区| a毛片免费全部播放自慰| 黑人粗大,爽| 亚洲av产在线精品亚洲第一站|