| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- RSA 密钥对生成与 License 签发工具
- 使用方法:
- python keygen.py genkey
- python keygen.py genlicense --expire "never" --product "laser_cal" --version "1.0.0" --licensee "客户名"
- """
- import os
- import sys
- import json
- import argparse
- import base64
- import uuid
- from datetime import datetime
- from pathlib import Path
- try:
- from cryptography.hazmat.primitives import hashes, serialization
- from cryptography.hazmat.primitives.asymmetric import rsa, padding
- from cryptography.hazmat.backends import default_backend
- except ImportError:
- print("错误: 缺少 cryptography 库,请先安装: pip install cryptography")
- sys.exit(1)
- BASE_DIR = Path(__file__).parent
- LICENSE_DIR = BASE_DIR / "dist" / "license"
- PRIVATE_KEY_FILE = LICENSE_DIR / "private_key.pem"
- PUBLIC_KEY_FILE = LICENSE_DIR / "public_key.pem"
- LICENSE_FILE = LICENSE_DIR / "license.lic"
- RSA_KEY_SIZE = 2048
- def ensure_dir():
- LICENSE_DIR.mkdir(parents=True, exist_ok=True)
- def generate_rsa_keys():
- """生成 RSA 密钥对"""
- ensure_dir()
- private_key = rsa.generate_private_key(
- public_exponent=65537, key_size=RSA_KEY_SIZE, backend=default_backend()
- )
- private_pem = private_key.private_bytes(
- encoding=serialization.Encoding.PEM,
- format=serialization.PrivateFormat.PKCS8,
- encryption_algorithm=serialization.NoEncryption()
- )
- public_pem = private_key.public_key().public_bytes(
- encoding=serialization.Encoding.PEM,
- format=serialization.PublicFormat.SubjectPublicKeyInfo
- )
- PRIVATE_KEY_FILE.write_bytes(private_pem)
- PUBLIC_KEY_FILE.write_bytes(public_pem)
- print(f"[成功] RSA 密钥对已生成:")
- print(f" 私钥: {PRIVATE_KEY_FILE}")
- print(f" 公钥: {PUBLIC_KEY_FILE}")
- print(f" 密钥长度: {RSA_KEY_SIZE} bits")
- print(f"\n[重要] 请妥善保管私钥文件,切勿泄露!")
- def generate_license(expire_date, product="laser_cal", version="1.0.0",
- licensee="default", max_instances=1):
- """生成 License 文件"""
- ensure_dir()
- if not PRIVATE_KEY_FILE.exists():
- print("[错误] 私钥文件不存在,请先执行 genkey。")
- sys.exit(1)
- private_key = serialization.load_pem_private_key(
- PRIVATE_KEY_FILE.read_bytes(), password=None, backend=default_backend()
- )
- license_data = {
- "license_id": str(uuid.uuid4()),
- "product": product,
- "version": version,
- "licensee": licensee,
- "issue_date": datetime.now().strftime("%Y-%m-%d"),
- "expire_date": expire_date,
- "max_instances": max_instances,
- "features": ["all"]
- }
- license_json = json.dumps(license_data, sort_keys=True, ensure_ascii=False)
- signature = private_key.sign(
- license_json.encode("utf-8"), padding.PKCS1v15(), hashes.SHA256()
- )
- license_content = {
- "license_data": license_data,
- "signature": base64.b64encode(signature).decode("utf-8")
- }
- LICENSE_FILE.write_text(json.dumps(license_content, indent=2, ensure_ascii=False), encoding="utf-8")
- print(f"[成功] License 文件已生成: {LICENSE_FILE}")
- print(f" License ID : {license_data['license_id']}")
- print(f" 产品 : {license_data['product']}")
- print(f" 版本 : {license_data['version']}")
- print(f" 被授权人 : {license_data['licensee']}")
- print(f" 过期日期 : {license_data['expire_date']}")
- def main():
- parser = argparse.ArgumentParser(description="RSA License 工具")
- subparsers = parser.add_subparsers(dest="command")
- subparsers.add_parser("genkey", help="生成 RSA 密钥对")
- lic_parser = subparsers.add_parser("genlicense", help="生成 License")
- lic_parser.add_argument("--expire", type=str, default="never")
- lic_parser.add_argument("--product", type=str, default="laser_cal")
- lic_parser.add_argument("--version", type=str, default="1.0.0")
- lic_parser.add_argument("--licensee", type=str, default="default")
- lic_parser.add_argument("--max-instances", type=int, default=1)
- args = parser.parse_args()
- if args.command == "genkey":
- generate_rsa_keys()
- elif args.command == "genlicense":
- expire = args.expire
- if expire.lower() != "never":
- try:
- datetime.strptime(expire, "%Y-%m-%d")
- except ValueError:
- print("[错误] 日期格式不正确,请使用 YYYY-MM-DD 或 'never'。")
- sys.exit(1)
- generate_license(expire, args.product, args.version, args.licensee, args.max_instances)
- else:
- parser.print_help()
- if __name__ == "__main__":
- main()
|