五步自建激活验证服务器:WebToApp 的 Cloudflare Worker 示例完整拆解
2026/9/16 14:16:56 网站建设 项目流程

五步自建激活验证服务器:WebToApp 的 Cloudflare Worker 示例完整拆解

【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app

WebToApp(一个完全运行在手机上、功能最全的 Web-to-App 工具箱,可把网页直接打包成 APK)内置了激活码验证功能。除了把码写死在 APK 里,它还支持远程激活:把码放到你自己搭建的服务器上,随时吊销、随时轮换,不用再重新打包 APK。本文带你完整拆解仓库里现成的 examples/remote-activation-worker 示例——一个跑在 Cloudflare Worker 上的自建激活验证服务器,从生成签名密钥、部署上线到写入激活码,五步全部走通。

为什么值得自建一个激活验证服务器?

本地激活码一旦打包进 APK,就"焊死"了:想吊销一个泄露的码?只能重新打包发布。换成远程验证后,一切变得灵活:

  • 🔄随时吊销:删掉服务器上的码,立刻失效,不用动 APK
  • 🔢动态发放:码库存放在 Workers KV,一条命令就能新增
  • 📱设备绑定:一码一次、单设备占用,靠服务器集中记账
  • 🔐签名响应:每个响应都用 EC P-256 签名,伪造服务器和中间人无法伪造ok: true
  • 零后端运维:Cloudflare Worker 按量计费、无需维护服务器

客户端协议完整定义在 remote-activation.md,App 端的校验逻辑实现在 RemoteActivationVerifier.kt,应用侧的配置说明见 activation.md。

示例目录结构一览

整个示例非常精简,就 4 个文件:

文件作用
src/index.jsWorker 主体:GET /自检 +POST /verify验码并签名
wrangler.toml部署配置:KV 绑定、时钟漂移容忍度
package.json脚本入口:check/dev/deploy/kv:create
test/protocol-check.mjs协议自检:模拟 KV 驱动真实 Worker,按 Android 客户端同款逻辑验签

第一步:生成 EC P-256 签名密钥对

安全设计的核心是非对称签名:Worker 用私钥签名,App 用公钥验签——公钥可以光明正大写进 APK,私钥只有 Worker 持有。用 OpenSSL 两条命令生成:

# 私钥(PKCS#8、单行 Base64)—— 作为 Worker 的 SIGNING_KEY openssl ecparam -genkey -name prime256v1 -noout -out ec.pem openssl pkcs8 -topk8 -nocrypt -in ec.pem -out ec-pkcs8.pem openssl base64 -A -in ec-pkcs8.pem -out ec-pkcs8.b64 # 公钥(SPKI Base64)—— 填进 App 的"Signature public key"字段 openssl ec -in ec.pem -pubout -out ec-pub.pem openssl base64 -A -in ec-pub.pem -out ec-pub.b64

⚠️ 私钥文件务必远离 git 仓库;公钥不是秘密,放心分发。

第二步:部署 Worker 到 Cloudflare

在 examples/remote-activation-worker 目录下:

npm install npx wrangler login npm run kv:create # 打印出的 id 粘贴进 wrangler.toml npx wrangler secret put SIGNING_KEY < ec-pkcs8.b64 npx wrangler deploy

密钥只通过wrangler secret put注入,绝不提交进仓库(见 wrangler.toml 的注释约定)。

部署完先在浏览器打开 Worker 地址自检。健康的 Worker 会返回类似这样的 JSON:

{ "ok": true, "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE…", "keyFingerprint": "3f9a1c02…", "urlEncryption": "disabled", "problems": [] }

publicKey直接复制进 App 的签名公钥输入框即可;problems非空则 Worker 会拒绝一切验证并告诉你原因(自检逻辑见 src/index.js)。

第三步:写入激活码(一条命令一个码)

码存在 Workers KV 里,键为code:大写码值:

# 不限次数的码 npx wrangler kv:key put --binding=ACTIVATION_CODES "code:DEMO1234" '{"note":"demo"}' # 固定到期 + 一码一设备 npx wrangler kv:key put --binding=ACTIVATION_CODES "code:YEAR2027" \ '{"expiresAt":1798761600000,"maxDevices":1,"devices":[]}' # 锁定指定包名,并下发加密的目标 URL npx wrangler kv:key put --binding=ACTIVATION_CODES "code:VIP0001" \ '{"packageName":"com.example.app","url":"https://example.com/target","encryptUrl":true}'

码记录的字段速查:

字段含义
expiresAt到期时间(epoch 毫秒),省略则永不过期
maxDevices可激活设备数(座位数),默认 1,即一码一次
devices已占座的设备 ID,由 Worker 自动维护
packageName设置后该码只对指定包名的 App 有效
url/encryptUrl动态下发目标 URL,可选 AES-256-GCM 加密(需配置AES_KEY机密)
message验证成功时展示给用户的消息
note你自己的备注,永远不会离开服务器

验码主流程(时钟校验 → 查码 → 过期/包名/座位检查 → 签名返回)集中在 handleVerify。

第四步:搞懂两个容易踩坑的协议细节

这正是示例最"值钱"的部分——两处细节写错,所有激活全部失败

1. 签名字段叫sig,不是signature客户端只认sig

2. 被签名的负载有固定键序。签名覆盖的是手工拼接的紧凑 JSON,键序为ok → expiresAt → remainingUses → nonce,开启 URL 下发时追加urlnull会被收敛成0(expiresAt)或-1(remainingUses)。Worker 端刻意不用JSON.stringify而是逐字段手拼(见 canonicalSignedPayload),就是为了与客户端逐字节一致,杜绝键序漂移。

配套的安全机制还包括:

  • 🧂Nonce 回显:每次请求带随机 nonce,响应原样带回,防重放
  • 时钟漂移检查:客户端时间戳与服务器偏差超过 24 小时(MAX_CLOCK_SKEW_MS,可在 wrangler.toml 收紧)直接拒绝
  • 📦URL 加密:开启encryptUrl时,目标 URL 先做 AES-256-GCM 加密(Base64(IV[12]‖密文‖GCM tag[16]),见 encryptUrl)再参与签名——防篡改靠签名,防偷读靠加密
  • 💺设备绑定deviceBound: true时按maxDevices记账,首台设备占座,卸载重装也不丢座

第五步:上线前跑一遍协议自检

改动任何逻辑后,先跑:

npm run check

test/protocol-check.mjs 用 mock KV 驱动真实的 Worker,再完全按 Android 客户端的方式复核:同款负载拼接、同款 ECDSA P-256(P1363 格式)验签、同款 AES-GCM 解包。README 说得直白:这是最快发现"会悄悄弄坏所有已安装 App"的改动的办法。

上线前必须知道的两件事 📌

1. URL 下发是"双边约定"。激活请求里不携带"我是否期望收到 URL"的标志,所以规则是:url的码,只配开了 Deliver target URL 的 App;不带的配没开的。配错后双方签的负载不同,每次激活的验签都会失败。

2. Workers KV 是最终一致、没有 compare-and-swap。两台设备同一瞬间抢最后一个座位时,可能都成功。对大多数 App 可接受;若不能接受,把记录存储换成 D1 或 Durable Object 即可——签名路径完全不变,只改get/put

💡 另外提醒:验证运行在客户端,远程验证的价值在于提高门槛(吊销、轮换、防伪造),而非防破解的银弹。详见 remote-activation.md 开头的安全说明。

写在最后

从生成密钥到跑通自检,整套流程不超过十分钟,而且全部跑在 Cloudflare 的边缘网络上——没有服务器要维护,没有数据库要备份。码在 KV 里增删改,App 侧只填一个 URL 和一把公钥。如果你的激活需求再复杂一点(比如按码查用户、扣减余额),也完全可以基于 src/index.js 这个约 300 行的参考实现往上加:只要签名负载的键序和字段名保持和 RemoteActivationVerifier.kt 一致,客户端就能无缝对接。🎉

【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询