为什么「只缓存上次结果」实际上不管用
显而易见的做法是把上次成功的检查记在本地文件或注册表里,下次跳过网络调用。这解决了离线问题,但什么都没验证——那只是磁盘上的一个字符串,任何拿着文本编辑器的用户都能把它从 false 改成 true。它也不会干净地过期(复制的文件在第二台机器上永远有效),也无法告诉你它究竟是何时被真正验证过的。你用「没有离线支持」换来了「离线支持根本不是一种检查」——这个文件是被信任的,而不是被验证的。
为什么自己手搓真正的离线验证比缓存一个标志位难得多
真正的离线验证意味着应用必须能够证明许可证有效,而无需询问服务器,只使用只可能来自该服务器的数据。这需要一对私钥/公钥(服务器签名,应用只持有公钥的一半)、一个包含许可证密钥、设备ID和过期时间的紧凑签名载荷(应用可以据此对照本地时钟检查)、一种让篡改可被检测的方法——翻转一个字节,签名就必须失效——以及一个决定:一个已签名但已过期的结果在应用被迫重新联网之前,还能被信任多久。这些都不是什么奇特的密码学,但要把它正确地接好——在解析载荷之前先验证签名、检查其中的每一项声明、选择一个合理的过期窗口——正是那种一次不小心出错、却永远不会被察觉的事情。
签名租约:服务器负责签名,应用只负责验证
这正是 SublimeKeys 离线验证所做的事。每次 activate/verify 调用都会返回一个租约(lease)——一个小型的 Ed25519 签名令牌,包含许可证密钥、设备ID、产品ID和一个有效期为 7 天的过期时间。你的应用将其缓存在本地,并用内置在你自己二进制文件中的公钥来验证签名——私钥永远不会离开我们的服务器,所以用户磁盘上没有任何东西可以被编辑成一个有效的租约。被篡改的租约会立即在签名验证阶段失败,甚至在其内容被解析之前。当 7 天窗口期结束后,下一次检查会悄悄联网,获取一个新的租约,循环往复——因此一台完全离线的机器一次最多可以在 7 天内保持可验证的授权状态,而被撤销的许可证会在机器下次重新联网时被捕获。
如何添加——用官方 SDK 三步搞定
这实际上能带给你什么
在正常的一天里,你的应用能以零网络调用、微秒级速度验证许可证;在飞行模式或被封锁的企业网络中坚持一整周仍能正常工作;即便如此,也能在机器重新联网后的 7 天内捕获到被撤销或退款的许可证——而这一切都不需要你自己编写一行密码学代码、托管密钥管理系统,或发明一种迟早会被人找到办法编辑的自定义令牌格式。
这实际上是为谁准备的
经常出差的用户
顾问、外勤工程师,任何笔记本会在航班和客户现场之间真正长时间离线的人。
封锁的企业网络
位于防火墙后、阻止一切未明确列入白名单的出站API调用的机器。
Python 桌面工具
pip install sublimekeys——离线验证已内置于官方 SDK。
Electron 应用
npm install sublimekeys——同样的签名租约验证,零原生依赖。
物理隔离/受监管环境
从不打算联网、只偶尔同步一次的机器。
About
Patrick Chen —— Sublimearts.io 背后的独立开发者。在意识到每一个卖给出差用户或企业用户的桌面应用迟早都会撞上同样的「没有网络」这堵墙之后,把离线验证做进了 SublimeKeys。
Did you find this helpful?