Skip to main content

LSY ODS 授权 SDK

Python PyPI License: MIT

lsyods-license-sdk 是 LSY ODS 提供的 Python 公用 SDK,用于机器身份识别、离线软件授权以及部署制品签名。SDK 提供稳定的机器指纹、安装实例 ID、Ed25519 许可证签发与校验、部署 ZIP 签名与验签,以及许可证状态判断等能力。

功能特性

  • 在 Windows 和 Linux 上计算带版本标识、不可逆的机器指纹。
  • 为不同产品生成独立的安装实例 ID。
  • 签发采用 Ed25519 数字签名的离线许可证。
  • 使用显式配置的可信公钥集合校验许可证和部署制品签名。
  • 将许可证与产品、软件版本、产品版本、安装实例 ID 和机器指纹绑定。
  • 判断订阅授权、永久授权、授权已过期和授权尚未生效等状态。
  • 通过 supersedes_license_id 保留许可证续期关系。
  • 将服务端确认的部署方式与 ZIP 摘要一起签名,供客户端独立验签。

产品版本表示 basicadvanced 等商业版本。具体功能或模块是否可用,由被授权产品根据商业版本自行判断。永久授权没有到期时间,但仍然只适用于签名声明中指定的软件版本。

安装

从 PyPI 安装:

pip install lsyods-license-sdk

使用 uv 安装:

uv add lsyods-license-sdk

SDK 要求 Python 3.10 或更高版本。

生成许可证签名密钥

SDK 提供 lsyods-license-keygen 命令,用于生成软件许可证专用的 Ed25519 密钥对。默认情况下,命令会要求输入密码,并使用该密码加密生成的私钥。

PowerShell 示例:

$env:LSYODS_LICENSE_KEY_PASSWORD = Read-Host "请输入密钥密码" -MaskInput

lsyods-license-keygen `
  --private-key D:\secure\license-private.pem `
  --public-key D:\secure\license-public.pem

命令执行成功后会输出公开的 key_idpublic_key_base64,供被授权产品配置可信公钥。私钥只能由受控的许可证签发服务访问,禁止将私钥或私钥密码分发到客户端或被授权产品中。

在具备可靠系统访问控制的自动化环境中,可以使用 --no-password 生成不加密的私钥。此时必须通过操作系统文件权限严格保护私钥文件。

机器指纹

from lsyods_license_sdk import calculate_machine_fingerprint

machine_fingerprint = calculate_machine_fingerprint()
print(machine_fingerprint)  # sha256:<64位小写十六进制字符>

SDK 使用带版本标识的域分隔符,对操作系统中相对稳定的机器标识进行哈希计算。返回结果不会包含原始的 Windows MachineGuid 或 Linux machine-id

部署制品签名

许可证签名和部署制品签名必须使用不同的密钥对。请使用 lsyods-artifact-keygen 为部署服务端生成专用的制品签名密钥,不要复用许可证签名密钥。

lsyods-artifact-keygen --private-key artifact-private.pem --public-key artifact-public.pem

该命令默认从 LSYODS_ARTIFACT_KEY_PASSWORD 环境变量读取私钥密码,并输出客户端配置所需的 key_idpublic_key_base64

服务端只会对已经通过安全审计和超级管理员审批的 ZIP 文件进行签名。部署方式由服务端审批记录提供,ZIP 中不需要额外的部署清单文件。

部署服务端和客户端通过 SDK 使用同一套制品签名协议:

from pathlib import Path

from lsyods_license_sdk import (
    create_artifact_signature,
    load_artifact_private_key,
    verify_artifact_signature,
)

package = Path("deployment.zip")
private_key = load_artifact_private_key(Path("artifact-private.pem"))
signature = create_artifact_signature(package, private_key, "powershell_deploy")

verified = verify_artifact_signature(
    package,
    signature,
    "powershell_deploy",
    {signature["key_id"]: "<public_key_base64>"},
    signature["sha256"],
)

许可证签名协议和部署制品签名协议使用不同的域分隔符。生产环境还必须为两类签名分别使用独立私钥,以便单独控制权限、轮换和吊销密钥。

签发许可证

许可证只能在受控的服务端环境中签发:

from datetime import datetime, timedelta, timezone
from pathlib import Path

from lsyods_license_sdk import (
    generate_installation_id,
    issue_license,
    load_private_key,
)

now = datetime.now(timezone.utc).replace(microsecond=0)
private_key = load_private_key(
    Path("D:/secure/license-private.pem"),
    password="private-key-password",
)

claims = {
    "license_id": "L260819000001",
    "issuer": "LSY ODS",
    "customer": "示例客户",
    "product": {
        "code": "example-product",
        "version": "V1.0",
        "edition": "advanced",
    },
    "installation": {
        "installation_id": generate_installation_id(),
        "machine_fingerprint": "sha256:" + "a" * 64,
    },
    "license_type": "subscription",
    "issued_at": now.isoformat(),
    "not_before": now.isoformat(),
    "expires_at": (now + timedelta(days=90)).isoformat(),
}

license_document = issue_license(claims, private_key)

签发永久许可证时,将 license_type 设置为 "perpetual",并将 expires_at 设置为 None

校验许可证

被授权产品只保存可信公钥,并根据当前产品、安装实例和运行机器校验本地许可证:

from lsyods_license_sdk import calculate_machine_fingerprint, verify_license

trusted_keys = {
    "<key_id>": "<public_key_base64>",
}

result = verify_license(
    license_document,
    trusted_keys,
    expected_product="example-product",
    expected_installation_id=installation_id,
    expected_machine_fingerprint=calculate_machine_fingerprint(),
)

if not result["valid"]:
    raise RuntimeError(f"许可证状态异常:{result['status']}")

licensed_version = result["claims"]["product"]["version"]
licensed_edition = result["claims"]["product"]["edition"]

被授权产品负责根据自身的版本兼容规则和功能开放规则,对 licensed_versionlicensed_edition 进行判断。

许可证续期

续期会生成一份新的签名许可证,同时沿用原有的安装实例 ID 和机器指纹。原许可证保持不变,仍然可以独立验签。新许可证声明中可以包含:

{
  "supersedes_license_id": "L260819000001"
}

该字段表示新许可证替代的历史许可证,便于保留完整的授权续期关系。

安全模型

  • 系统安全依赖于妥善保护 Ed25519 私钥,而不是隐藏 SDK 的实现代码。
  • 被授权产品和部署客户端只能信任明确配置的公钥。
  • 许可证和制品签名文档在完成签名后必须视为不可变数据。
  • 机器指纹是设备标识,不是身份认证密码或安全凭据。
  • 离线授权无法阻止客户修改其完全控制的应用程序,被授权产品应在合适的信任边界执行授权检查。
  • 密钥轮换时,应先将新公钥加入可信公钥集合,再使用新私钥签发许可证或签名制品。
  • 许可证私钥与部署制品私钥必须分别存储、分别授权和分别轮换。

开发与构建

项目使用 uv 管理依赖,并通过 pyproject.toml 配置阿里云 PyPI 镜像:

uv sync --locked
uv run pytest
uv run pyflakes src tests
uv build --no-sources

开源许可

Copyright (c) 2026 成都领数云科技有限公司。

本项目基于 MIT 许可证 开源。

Release files for lsyods-license-sdk 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lsyods-license-sdk 0.3.0
File Size Uploaded
lsyods_license_sdk-0.3.0.tar.gz 17.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lsyods-license-sdk 0.3.0
File Interpreter ABI Platform
lsyods_license_sdk-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size:32.0 kB

Release files / lsyods_license_sdk-0.3.0.tar.gz

Download URL lsyods_license_sdk-0.3.0.tar.gz
Size 17.5 kB
Tags Source
SHA-256 checksum
How to use checksums
ab90bc5599c421478bc78bf8b67688edeb7bbab1bef8b64acffc6bc06d25dbef
BLAKE2b-256 checksum
How to use checksums
1bbcec99596ed3f2a36948d02d2c7fe2e16ae677476e572c0a30597053229e9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.11

Release files / lsyods_license_sdk-0.3.0-py3-none-any.whl

Download URL lsyods_license_sdk-0.3.0-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
37f86aa69cfc3b7c9460aeda56161aa38c7f01902e4017b782b7cad4ec32e12d
BLAKE2b-256 checksum
How to use checksums
444d0845db0dafc474e8051687cbd0ab3e07bbbf5b396a0976a89d3717cfd7b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.11

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page