如何为Python程序设置用户使用时长限制?
Python商业程序使用时长限制实现方案
针对你要给售卖的Python程序添加使用时长限制的需求,这里提供几种实用的实现思路,兼顾安全性和可操作性:
核心思路
程序启动时校验当前时间是否超过预设的到期时间,校验不通过则终止运行。关键在于防止用户篡改校验数据,毕竟商业场景需要避免被轻易破解。
实现方案(从基础到进阶)
1. 加密本地校验(适合中小规模商业场景)
用对称加密存储到期时间,避免用户直接修改本地文件篡改到期日期。这里用cryptography库的Fernet加密,简单可靠。
步骤1:生成加密密钥(仅你自己保存,绝不分发)
运行一次以下代码,生成并保存密钥:
from cryptography.fernet import Fernet # 生成密钥 key = Fernet.generate_key() # 保存到本地安全位置 with open("your_secret.key", "wb") as f: f.write(key)
步骤2:为用户生成加密的到期时间
根据用户购买的时长,生成加密后的到期时间字符串,发给用户(比如写入auth.txt让用户放到程序目录):
from cryptography.fernet import Fernet from datetime import datetime, timedelta # 加载你的密钥 with open("your_secret.key", "rb") as f: key = f.read() cipher = Fernet(key) # 示例:设置用户可使用30天(从生成日起) expiry_date = datetime.now() + timedelta(days=30) # 转成时间戳加密 encrypted_expiry = cipher.encrypt(str(int(expiry_date.timestamp())).encode()) # 输出加密后的字符串,发给用户 print("用户授权码:", encrypted_expiry.decode())
步骤3:程序启动时的校验逻辑
在程序入口添加校验代码,不通过则退出:
from cryptography.fernet import Fernet, InvalidToken from datetime import datetime import sys def validate_expiry(encrypted_code, key): try: cipher = Fernet(key) # 解密到期时间戳 decrypted_ts = int(cipher.decrypt(encrypted_code.encode()).decode()) current_ts = int(datetime.now().timestamp()) if current_ts > decrypted_ts: print("⚠️ 程序使用时长已耗尽,请联系作者续费。") sys.exit(1) # 可选:显示剩余时长 remaining = datetime.fromtimestamp(decrypted_ts) - datetime.now() print(f"✅ 程序剩余使用时长:{remaining.days}天{remaining.seconds//3600}小时") except InvalidToken: print("❌ 无效的授权信息,请检查授权码或联系作者。") sys.exit(1) except Exception as e: print(f"❌ 授权校验失败:{str(e)}") sys.exit(1) # 加载用户的授权码(假设用户把授权码存在auth.txt) with open("auth.txt", "r") as f: user_auth_code = f.read().strip() # 加载你的密钥(注意:不要硬编码!可以通过混淆或硬件绑定方式嵌入程序) with open("your_secret.key", "rb") as f: secret_key = f.read() # 执行校验 validate_expiry(user_auth_code, secret_key) # 校验通过,启动主程序 print("程序启动中...") # 你的主逻辑代码
2. 进阶安全优化
- 避免硬编码密钥:可以结合用户的硬件信息(如MAC地址、硬盘序列号)生成动态密钥,即使程序被反编译,用户也无法复用授权码到其他设备。
- 网络时间校验:如果程序允许联网,请求NTP服务器获取标准时间,防止用户篡改系统时间绕过校验。示例代码:
import ntplib from datetime import datetime def get_ntp_time(): try: client = ntplib.NTPClient() response = client.request('pool.ntp.org') return datetime.fromtimestamp(response.tx_time) except: # 网络失败时 fallback 到本地时间 return datetime.now()
- 代码混淆:用
pyarmor等工具对Python代码进行混淆加密,防止用户反编译修改校验逻辑。 - 在线授权服务器:如果预算允许,搭建简单的授权服务器,每次启动请求服务器校验到期时间,安全性最高,但依赖网络。
注意事项
- 没有绝对安全的方案,以上方案是在安全性和开发成本之间的平衡,适合中小规模商业程序。
- 给用户的授权文件/码要做好分发管理,避免泄露或重复使用。
内容的提问来源于stack exchange,提问作者Vibez
相关产品推荐
相关产品推荐

