软件许可证文件生成软件
在写好软件以后,往往需要将软件打包发送给用户进行使用。但是若只希望给特定的用户进行使用,那么就需要将软件设置License(许可证)。本篇文章就来提供一种生成license文件的思路。

1、前言
软件开发商完成一个软件的模块,希望交付给用户进行使用。软件开发商一般是希望只授权给某些用户使用,而不希望软件被其他未授权用户进行使用。因此需要开发一个软件授权的机制。
当用户安装或者第一次使用软件的时候,软件是没有被授权的。当用户希望将软件绑定到某一台特定的计算机进行使用时,需要将目标计算机的MAC地址告知软件开发商,收到开发商的授权以后就能正常使用软件了。
软件开发商收到授权请求时,获得软件安装的目标计算机的MAC地址。通过一套绑定mac地址的算法,生成了一个license,并且具有license失效的时间。生成的license同软件中内置的同一套算法生成的信息进行比对,如果比对上,那么授权成功。如果比对不上或者授权过期,那么授权失败。
2、软件License的实现办法
[暂无]
3、使用PyQt5开发
3.1 框架
1、获取目标计算机的mac地址
2、设置license过期的时间
3、对mac和授权时间进行加密
3.2 算法
算法的核心就是,对mac地址进行hash计算。为了增加生成的license文件的困难度,在mac地址之前再加上一个特定的字符,让该license生成软件的破解难度可以稍微提高。例如在这里的示例代码中,特定字符暂定为first_key。
Hash算法的特点是,HASH的设计以无法解为目的;简单说来就是正向简单,逆向困难。
#1、得到密钥,通过hash算法计算目标计算机的mac地址
psw = hash_msg('first_key' + str(self.mac_addr))
#2、新建一个license_str 的字典,用于保存真实的mac地址,license失效时间,加密后的字符串
license_str = {}
license_str['mac'] = self.mac_addr
license_str['time_str'] = self.active_date
license_str['psw'] = psw
生成的lincense_str作为一个字典,写入license文件中,是可以很直接地看出其组成。
因此为了更进一步加密,保证写入license文件中地信息是无序且无意义地字符串,采用AEScoder进行加密
from AEScoder import PrpCrypt
pc = PrpCrypt('keyskeyskeyskeys') # 初始化密钥
s_encrypt = pc.encrypt(str(license_str())) # <class 'bytes'>
AES只有一个密钥,这个密钥既用来加密,也用于解密。例如在上面地示例代码中,采用了keyskeyskeyskeys作为密钥。该密钥在license生成软件中作为加密密钥,同时在使用license地软件中作为解密密钥。
from AEScoder import PrpCrypt
pc = PrpCrypt('keyskeyskeyskeys') # 初始化密钥
d = pc.decrypt(s_encrypt) # 解密
将生成的license文件保存到特定的文件中,即完成了license的生成。
# file_path即保存的文件路径
# mac_str 是目标计算机的mac地址字符串
# time_str 是授权目标计算机的使用时间,可以认为是license文件的失效时间
file_path = self.file_path + '/license_'+ mac_str + '_' + time_str + '.lic'
s_encrypt = str(s_encrypt, encoding = "utf-8") # bytes to str
with open(file_path, 'w', encoding='utf-8') as lic:
lic.write(str(s_encrypt))
lic.close()
3.3 代码实现
利用Hash算法对一段字符进行运算
python中实现对一段字符的运算时比较简单的,如下提供了一个示例代码。
import hashlib
def hash_msg(msg):
sha256 = hashlib.sha256()
sha256.update(msg.encode('utf-8'))
res = sha256.hexdigest()
return res
获取本机的mac地址
def get_mac_address():
mac = uuid.UUID(int = uuid.getnode()).hex[-12:]
return ":".join([mac[e:e+2] for e in range(0,11,2)])
pyqt5实现界面
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
loadUi("Generator.ui", self)
self.resize(405,480)
self.setMinimumSize(QtCore.QSize(415,490))
self.setMaximumSize(QtCore.QSize(415,490))
self.setWindowTitle('******软件激活码生成器')
self.setWindowIcon(QIcon('admin.ico'))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
生成的license文件的字符串

665dbda2a88fc8694d0df10e120236fd481087bd3e4d02c86f36ecba5d10eec24f5f0f5c8afb24cd8ee10c72df3c1d567a796c03a5095be96fdd1438e8121f0d780e6fc00784a1be9788661a7b18ed6e73e2ec337b251ede0f0be8f7287e63f0c69f202550dd45db55b62da9c886ba9da25165a6dd253ea9efe5a29e9637941c0d0a0b1cc1c6f01225e6f61eaf520f24
如果您感兴趣,可以通过以上算法生成激活码。
4、程序打包
使用PyInstaller将license文件生成软件进行打包
一般常规的打包代码是:
python -m PyInstaller -F license_generator.py
如果想要给软件增加一个好看的图标,可以在打包的代码中加上打包图标的参数。
python -m PyInstaller -F license_generator.py -i icon.ico
在使用pyinstaller模块对pyqt5的程序进行打包的时候往往需要增加几行代码,用于指定其路径。
def app_path():
"""Returns the base application path."""
if hasattr(sys, 'frozen'):
# Handles PyInstaller
return os.path.dirname(sys.executable) # 使用pyinstaller打包后的exe目录
return os.path.dirname(__file__) # 没打包前的py目录
PROJECT_PATH = app_path()
5、结尾
1、该方法仅提供一种思路,即对mac地址和实效时间进行加密,生成字符。
2、如果需要提供源代码进行调试,或者代为开发请联系。