提问背景 Question:
这里有二个问题,第一。为了安全,私钥是必须保存在官方服务器中的,也不能编译中代码中。第二。我们不可能给我们用户去编译一套程序,所以公钥只能明文的发给用户,让程序去读取。你刚才的说法应该是利用私钥+内容,生成公钥。然后进行验证。那么离线情况下怎么办?
RSA 离线授权机制详解:公私钥配合与防伪原理
您的直觉非常敏锐,并且问到了软件授权安全中最核心的逻辑。但这里您对 RSA 的工作原理以及**“公钥和私钥的分工”**产生了一个关键的误解。
我们不需要为每个用户编译不同的代码,所有用户拿到手的程序(包含公钥)都是完全一模一样的。同时,用户拿到公钥,也绝对无法自己制作授权码。
下面为您彻底梳理“离线授权”的闭环逻辑,解答您的所有疑问:
纠正一个关键概念误解
- 错误的理解:用“私钥 + 内容”生成“公钥”去验证。(❌)
- 正确的理解:公钥和私钥是一对固定生成的钥匙。在软件发布前就已经定死了。公钥绝对无法通过私钥和内容计算出来,公钥和私钥是一起由开发者提前生成的。(
第一部分:为什么“公钥一样”且“公开”是绝对安全的?
非对称加密的核心魅力在于:公钥只能用来“验签”(验证真伪),只有私钥才能“签名”(制作授权)。
1. 软件里公钥相同,会不会泄露?
是的,公钥是公开的。即使别有用心的人把您的程序反编译,拿到了这个公钥,也完全没有关系。
2. 为什么拿到公钥无法伪造授权?
因为要制作一个可以通过公钥验证的授权文件,必须使用私钥进行签名计算。在数学上,哪怕全世界都知道您的公钥,在没有私钥的情况下,也绝对无法反推出私钥,更无法伪造出任何可以通过该公钥验证的签名。
所以:
- 私钥(1个):死死锁在您的官方服务器,负责生产授权码。
- 公钥(1个):写死在代码里分发给所有人,负责检查授权码。
第二部分:离线状态下,授权是如何验证的?
离线验证的完整流程如下,完全不需要网络连接:
第一步:用户购买(在线生成授权)
- 用户在您网站购买,输入了他的信息:
- IP:
192.168.1.100 - 到期时间:
2026-12-31 - 版本:
Professional
- IP:
- 您的官网后台服务器(拥有私钥)将这些文本拼接,用私钥进行签名,生成一串密文(即 Signature 签名)。
- 您的系统把 [原始文本] 和 [签名] 拼接在一起,作为
license.lic许可证文件发给用户。
最终的 License 文件内容长这样(一般会进行 Base64 编码):
{ "data": { "ip": "192.168.1.100", "expire": "2026-12-31", "edition": "Professional" }, "signature": "Ux8aD92kLa...[这是一串用私钥生成的签名密文]" }
第二步:用户在离线环境部署(离线验签)
用户把这个 license.lic 放到他那台完全断网的服务器上,启动您的软件:
- 软件读取文件:软件读取到
data(明文数据)和signature(签名)。 - 软件调用公钥验证:软件利用代码里内置的公钥,对
signature进行解密和数学校验。- 校验原理:公钥解密签名后,比对解密出来的哈希值是否与当前
data的哈希值完全一致。 - 结果 A(验证通过):说明这个
data确实是由拥有私钥的官方服务器颁发的,且中间没有被篡改过。 - 结果 B(验证失败):如果用户自己修改了
data里的过期时间(比如改成 2099 年),或者自己胡乱写了一个签名,公钥验签就会立即失败,软件拒绝运行。
- 校验原理:公钥解密签名后,比对解密出来的哈希值是否与当前
- 本地规则检查:验证签名合法后,软件在本地对比当前系统时间是否超过
2026-12-31,对比当前网卡 IP 是否是192.168.1.100。全部通过,则软件正常授权运行。
这就是完整的离线验证。整个过程,软件没有向外界发送任何网络请求,全部在本地用硬编码的公钥完成校验。
总结:安全性与局限性
| 角色 | 存放位置 | 作用 | 泄露后果 |
| :--- | :--- | :--- | :--- |
| 私钥 (Private Key) | 您的云端服务器(严格保密) | 用来给用户的购买信息生成签名(制作授权书) | 毁灭性灾难。泄露后人人都可以无限制作授权书。 |
| 公钥 (Public Key) | 编译在客户端代码中(公开) | 用来验证签名是否是由官方私钥生成的 | 无任何安全影响。拿到公钥的人也只能用来验证,无法伪造。 |
离线授权唯一的破绽是什么?
既然算法无法破解,黑客会怎么做?
- 修改系统时间:用户可以通过修改服务器的系统时间来绕过过期限制。对策:软件可以记录上次运行时间,若发现当前时间小于上次运行时间,判定为作弊。
- 逆向破解(爆破):黑客不破解 RSA 算法,而是直接修改您编译后的二进制代码,定位到验证授权的
if (verified == true)分支,强行将其修改为if (true)。这是所有单机/离线软件(如 Photoshop、Office 各种破解版)共同面临的宿命。对策是做代码混淆、加壳保护,提高逆向门槛。