3.9 KiB
3.9 KiB
chongming-license
机器码授权共享包:硬件指纹采集、license 载荷格式、Ed25519 验签与插件白名单判定。 网关与厂商侧签发工具共用同一份实现 —— 尤其是规范化 JSON 只有一处实现, 避免"自己签的自己验不过"。
设计要点
- 纯离线:设备用内置公钥验签,运行期零联网。与现有 air-gapped 部署形态
(Zenoh localhost、Caddy
tls internal、无 phone-home)一致。 - 非对称:Ed25519。注意根仓
resources/*.key那套.mbank验签是 HMAC 对称且密钥与银行同目录发布,只能算防篡改/混淆,不能作为厂商 信任根 —— 授权必须用非对称,公钥可安全内置。 - N-of-M 容错:license 里存各来源的原始指纹,校验按"命中数达阈值"判定,
而非把所有来源哈希成一个值 —— 否则换一块网卡就直接失效。
展示给客户的仍是单个
machine_code。 - weak 来源:
/etc/machine-id在同镜像批量刷机场景下所有机器相同, 故标记weak且不参与判定阈值(只作诊断参考),避免它给攻击者白送一票。
采集来源
| 来源 | 位置 | 说明 |
|---|---|---|
board_serial |
/proc/device-tree/serial-number、DMI board_serial |
逐机唯一,最稳定 |
emmc_cid |
/sys/block/mmcblk*/device/cid |
芯片出厂唯一,不随系统重装变化 |
cpu_serial |
/proc/cpuinfo 的 Serial |
ARM 常见;部分型号全 0(会被剔除) |
mac |
/sys/class/net/*/address |
取字典序最小者:插入/移除其它网卡不改变它 |
product_uuid |
/sys/class/dmi/id/product_uuid |
x86 有效,ARM 通常缺失 |
machine_id |
/etc/machine-id |
⚠ weak,见上 |
文件格式
{
"payload": {
"v": 1,
"lic_id": "L2026-0001",
"customer": "某某科技",
"machine_code": "A3F9-1B77-9E04-2C8D-6F31-0A55",
"sources": {"board_serial": "...", "emmc_cid": "...", "mac": "..."},
"plugins": ["aibox_sophon_adapter", "ip_sound_column"],
"not_before": "2026-09-01",
"expires_at": "2027-09-01",
"issued_at": "2026-09-01T10:00:00Z",
"note": ""
},
"alg": "ed25519",
"kid": "vendor-2026",
"sig": "<base64,覆盖 payload 的规范化 JSON>"
}
签名覆盖 payload 原始字节的规范化形式(canonical_json:键排序、无空白),
因此载荷内不允许浮点数(float 文本表示存在多种合法写法)。校验顺序是
先验签、后解析模型 —— 反过来会让默认值填充/字段顺序改变字节导致验签失败。
用法
网关侧:
from chongming_license import LicenseManager
mgr = LicenseManager(
license_path="license.lic",
public_key=config["license"]["public_key"],
clock_store=cache, # chongming_cache.Cache,存时间高水位
enforce=is_packaged(), # 打包产物强制校验;开发/测试放行
)
decision = mgr.check_plugin("aibox_sophon_adapter")
if not decision.allowed:
... # 不加载该插件
厂商侧(chongming-cli,私钥只在这边):
uv run chongming-license keygen -o license_private.pem # 一次性生成密钥对
uv run chongming-license issue --machine-code <码> --sources-json <采集导出> \
--plugins aibox_sophon_adapter,ip_sound_column \
--customer 某某科技 --expires 2027-09-01 -k license_private.pem -o license.lic
诚实的边界
离线 + root 的天花板是阻止随手拷贝,不是阻止逆向:有 root 者可改二进制
跳过校验,或 LD_PRELOAD 伪造指纹读取。clock 模块的时间回拨检测同理 ——
删掉缓存文件即失效,它只是抬高随手改时间的门槛。
真正难以绕过的是签名:伪造 license 需要厂商私钥,而公钥可明文放置 (换公钥只会验签失败,无法据以伪造)。