#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ License 验证模块 """ import sys import json import base64 import os from datetime import datetime from pathlib import Path try: from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.backends import default_backend from cryptography.exceptions import InvalidSignature except ImportError: print("错误: 缺少 cryptography 库") sys.exit(1) PRODUCT_NAME = "laser_cal" def _get_base_dir(): """获取程序基础目录""" if getattr(sys, 'frozen', False) or '__compiled__' in dir(): # 如果是被打包的程序,寻找当前执行路径的目录 return Path(sys.executable).parent # 开发环境下,如果是从共享库加载,__file__ 指向当前文件 return Path(__file__).parent def _find_file(filename): """在可能的位置查找文件""" # 1. 尝试当前执行文件目录 base = _get_base_dir() if (base / filename).exists(): return base / filename # 2. 尝试当前工作目录 cwd = Path.cwd() if (cwd / filename).exists(): return cwd / filename # 3. 尝试开发环境下的 dist/license 目录 dev_path = Path(__file__).parent / "dist" / "license" / filename if dev_path.exists(): return dev_path return None def verify_license(verbose=False): """验证 License 文件""" license_path = _find_file("license.lic") pubkey_path = _find_file("public_key.pem") if not license_path: if verbose: print(f"[授权错误] License 文件 (license.lic) 不存在") return False if not pubkey_path: if verbose: print(f"[授权错误] 公钥文件 (public_key.pem) 不存在") return False try: license_content = json.loads(license_path.read_text(encoding="utf-8")) license_data = license_content["license_data"] signature_b64 = license_content["signature"] except (json.JSONDecodeError, KeyError): if verbose: print("[授权错误] License 文件格式无效") return False try: public_key = serialization.load_pem_public_key( pubkey_path.read_bytes(), backend=default_backend() ) except Exception: if verbose: print("[授权错误] 公钥加载失败") return False # 验证 RSA 签名 try: license_json = json.dumps(license_data, sort_keys=True, ensure_ascii=False) signature = base64.b64decode(signature_b64) public_key.verify( signature, license_json.encode("utf-8"), padding.PKCS1v15(), hashes.SHA256() ) except InvalidSignature: if verbose: print("[授权错误] License 签名验证失败,文件可能被篡改") return False except Exception: if verbose: print("[授权错误] 签名验证过程出错") return False # 检查过期日期 expire_str = license_data.get("expire_date", "") if expire_str.lower() != "never": try: expire_date = datetime.strptime(expire_str, "%Y-%m-%d") if datetime.now() > expire_date: if verbose: print(f"[授权错误] License 已过期: {expire_str}") return False except ValueError: if verbose: print("[授权错误] 过期日期格式无效") return False # 检查产品名 if license_data.get("product", "") != PRODUCT_NAME: if verbose: print("[授权错误] License 产品不匹配") return False if verbose: print(f"[授权验证] 通过 | {license_data.get('licensee')} | 过期: {expire_str}") return True def get_license_info(): """获取 License 信息""" license_path = _find_file("license.lic") if not license_path: return {} try: content = json.loads(license_path.read_text(encoding="utf-8")) return content.get("license_data", {}) except Exception: return {} if __name__ == "__main__": verify_license(verbose=True)