Appearance
HiAPI 授权保护 —— 最终方案与分阶段开发计划
本文件是权威版,自包含。新会话只需读:本文件 + 记忆库
project_license_protection.md。 (早期的hiapi-cloud-public授权与代码保护方案.md、GraalVM可行性验证清单.md走的是已被推翻的 GraalVM/保密路线,已删除。)
0. 真实目标(一切的前提,别再跑偏)
系统本身没有核心算法。用户要的不是"防反编译 / 保密代码",而是三件事:
- 控制:没有我的授权,系统跑不起来;可远程限制租户数/实例数、可吊销。
- 威慑:客户不敢随意滥用、不敢把源码丢到网上。
- 心理:让客户觉得里面加密了重要东西,从而不敢动。
核心认知:客户本地完整运行 + 有代码 → "无法破解"不可能、也不需要。目标是"让老实人没动力、让坏人有成本有风险",靠的是 控制闸门 + 联网授权 + 水印追溯 + 合同,不是加密强度。
1. 方案总览
做法:把一个启动必需(load-bearing)的模块加密,启动时联网到授权服务器校验、按客户密钥下发、本地解密加载进 JVM。没授权/超额 → 拿不到模块 → 系统起不来。
为什么选 hiapi-core-public 当闸门:它是登录/验证码/上传(34 文件,2838 行)。抠掉它=没法登录=系统是死的。它不值钱(无算法)但不可或缺,是理想的控制闸门。
四道牙齿:
- 起不来:闸门模块不在 → 无法登录 → 系统不可用。
- 联网授权:激活/心跳/配额在你服务器(nuwa),可限制、可吊销、可发现滥用。
- 每客户水印:泄漏到网上能追到是谁。
- 合同:法律兜底。
诚实边界:有能力的人能脱掉闸门——改变不了。但①绝大多数客户不会逆向(perception 即挡住)②动了能被 phone-home 发现③水印追人④合同起诉。对目标足够。
2. 明确不做 / 已否决(别在新会话里重新探讨)
| 否决项 | 原因 |
|---|---|
| GraalVM Native Image | 闸门是被客户 JVM 应用加载的库,不是独立服务;native image 编不出可被 JVM 加载、Spring 扫描的产物。(技术栈本身能 native,已验证,但此场景不适用) |
| 买 Zelix(贵) | hiapi-core-public 是编排样板+标准件(标准 RSA + 开源烂大街的滑块验证码),不值这个钱。用免费 ProGuard。 |
| 信封加密客户数据 | 数据是客户自己的,他删掉加密存明文即可,防不住。 |
| 把逻辑搬 native 重写 | 没有值得保护的算法。 |
| 追求"无法 dump / 不可破解" | 不可能,且对本目标不必要。 |
3. 涉及的工程与现状
- 授权服务端:现
hiapi-cloud-license-server(Go),迁入并合并到hiapi-cloud-nuwa(hiapi-cloud-appstore,Go,Gin+GORM/MySQL) 的internal/license。 - 加载器:现
hiapi-core-cpp(JNI + OpenSSL + 反调试)+ Java 侧hiapi-fast-frame/hiapi-fast-core/hiapi-core-license/.../HiapiCloudLicense.java(CommandLineRunner,static 块 System.load .so,initAuthorization 下载解密 DefineClass + 心跳)。思路保留,修正后用。 - 闸门模块:
hiapi-fast-frame/hiapi-fast-core/hiapi-core-public(不随源码交付,加密下发)。 - 宿主应用:
hiapi-cloud-public(源码交付给客户,客户自己 build 成 JVM 应用;依赖 hiapi-core-public)。
现有已知 BUG(必须修)
HiapiCloudLicensestatic 块:Windows 上Files.delete已System.load的 DLL 会抛异常 → 启动崩。- 心跳/连接失败
exit(0):会把客户生产进程拖垮;且授权服务器一抖动全体崩。 - C++
loadClass的 DefineClass 循环里多一个i++(应删)。 - AES key/iv 全网硬编码且写死(
oFUtQE7...),jar 放公开 OSS——必须改按客户密钥 + 服务器下发。 - nuwa/license-server 授权是桩:clientId 写死
1000,心跳永远返回正常——要做成真校验。
4. 分阶段开发计划(按顺序)
贯穿原则:每个强制点挂开关,默认监控/宽松;现网先激活并 grandfather;启动失败要干净(这正是"起不来"),但运行中断网给宽限别崩;任何阶段可独立回退。
阶段 0 · nuwa 授权服务地基(牙齿,和生产隔离,最先做)
目标:把真授权能力建起来,先不接客户端。 任务:
internal/license/领域 +internal/httpapi/license_handler.go+internal/repository/license_repo.go。- 数据表(MySQL/GORM):
customers(套餐、max_instances、max_tenants、到期、状态)installs(install_id、customer、首次激活、状态)instances(instance_uuid、install_id、最近心跳、出口IP)—— 浮动并发计数tenant_grants(已发租户名额)module_keys(每客户的模块解密密钥)encrypted_modules(按客户加密的 hiapi-core-public 产物,或存对象存储的引用)watermarks(customer ↔ 水印标识)revocations(吊销列表)
- Ed25519 签发/验签(弃旧 RSA 分块)。
- 接口(TLS + 签名 + nonce/timestamp 防重放):
POST /license/activate→ 校验授权key+配额 → 生成/返回 install_id + 签名票据POST /license/heartbeat→ 浮动计数、刷票据、下发吊销、克隆检测POST /license/module/fetch→ 校验授权 → 返回按客户密钥加密的闸门模块POST /license/tenant/report→ 上报租户数 → 超额检测/告警- 管理后台:客户/配额/水印 管理(复用 nuwa 现有 bearer-token 中间件) 生产影响:无。 完成判据:能独立联调激活/心跳/下发/配额。
阶段 1 · 加载器修正 + 按客户密钥下发
目标:客户端接上真授权,闸门成型。 任务:
- 加载器联 nuwa(替换写死域名),激活拿票据 + install_id(存 K8s Secret/PVC)。
- 从 nuwa 下发加密闸门模块(替换公开 OSS);按客户独立 AES 密钥(替换硬编码)。
- 本地解密 → DefineClass 加载(沿用现机制,修掉
i++bug)。 - 修 Windows 删 .so 崩(加载后不删 / deleteOnExit)。
- 去掉裸
exit(0):启动期无授权/超额 → 干净拒绝启动(这就是"起不来");运行期断网 → 离线宽限期(建议 7~14 天)后降级,不崩生产。 - 机器/install 绑定(k8s 用 install_id,不用硬件指纹)。 生产影响:先监控模式(只激活+心跳+日志,不强制);给现网先激活、grandfather。带 kill-switch。 完成判据:现网在监控模式稳定;下发/解密/加载链路通;bug 全修。
阶段 2 · 配额强制(实例 / 租户)
目标:真正能"控制开通多少租户/多少实例"。 任务:
- 浮动并发实例计数(心跳统计同时在线 instance_uuid,对照
max_instances,停心跳 60~90s 回收)。 - 租户配额(创建租户处校验 +
tenant/report对账)。 - 克隆检测(同 install_id 多出口IP/集群并发 → 标记/吊销)。
- 强制力度:alert-only → 软提示 → 硬拒绝新增超额;已在跑的放行。 生产影响:逐项、逐 install 灰度。 完成判据:超额能拦/能告警;老实例不受影响。
阶段 3 · 水印 + ProGuard 混淆
目标:可追溯 + 增强"加密感"。 任务:
- 每客户独立构建,注入唯一水印(无害常量/资源顺序/隐写 ID),入库
customer ↔ 水印。 - 免费 ProGuard 过一遍 hiapi-core-public(配好 Spring keep 规则:实体、DTO、Controller、@Service 名等不能乱改)。
- (可选)保留简化版 native 加载器/反调试,纯为"加密感"+抬高随手门槛,不依赖其保密。 生产影响:改构建,不动运行数据;需功能回归。 完成判据:泄漏样本能提取水印定位客户;混淆后功能正常。
阶段 4 · 上线 + 退役旧件 + 合同
任务:
- 全量启用强制(确保所有 install 已激活、在配额内)。
- 下线
hiapi-cloud-license-server,域名指向 nuwa。 - 清理
hiapi-core-cpp中已废弃部分(加密 jar/OSS/硬编码 key),保留修正后的加载器;归档不用的。 - 授权合同条款写清:授权范围、实例/租户上限、禁止转售/公开源码、审计权、违约责任。 完成判据:旧服务下线;合同到位。
5. 生产安全红线(贯穿所有阶段)
- 现有加载器的
exit(0)和 Windows 删 .so 会崩生产,阶段 1 必修。 - 升级先监控模式,现网先激活 + grandfather。
- 启动失败=干净拒绝(要的就是这个);运行中断网=宽限+降级,绝不崩。
- 授权服务器要高可用 + 客户端缓存票据,避免你一抖动全体客户挂。
- 每个强制点挂开关,可独立回退。
6. 优先级(性价比)
- 阶段 0 nuwa 真授权 + 配额 + 水印登记(牙齿,先做,隔离生产)。
- 阶段 1 加载器修正 + 按客户下发(闸门成型 + 修崩生产的 bug)。
- 阶段 2 配额强制(实现"控制租户/实例数")。
- 阶段 3 水印 + ProGuard(追溯 + 加密感,免费)。
- 阶段 4 上线退役 + 合同。
一句话:牙齿在"联网授权+配额+水印+合同",加密只是让闸门有"加密感"+挡懒人。把力气按上面顺序花,别在保密强度上烧钱。