如何防止公钥被替换和许可证伪造?License3j防欺诈安全实践清单 📅 2026/8/24 12:08:26 如何防止公钥被替换和许可证伪造License3j防欺诈安全实践清单【免费下载链接】License3jFree Licence Management Library项目地址: https://gitcode.com/gh_mirrors/li/License3jLicense3j 是一款免费的 Java 许可证管理库它能创建、读取并验证带电子签名的许可证文件。但很多新手只做了签名却没注意到如果公钥本身能被替换整个签名验证就会形同虚设。本文以 License3j 的源码实践为线索给你一份防止公钥替换和许可证伪造的完整安全清单。先弄清为什么你的公钥会被人替换License3j 的防伪造逻辑建立在非对称加密上许可证用只有你才持有的私钥签名客户端用公钥验证签名。没有私钥攻击者数学上无法伪造合法签名——这正是签名提供的不可抵赖性。但这里有个常被忽视的漏洞公钥如果以资源文件形式放在 jar/war 包里格式又足够简单任何新手都能用 ZIP 工具把 key 文件换成自己的然后给自己发许可证公钥被替换后攻击者用自己生成的新公钥去验证伪造的许可证isOK()照样返回true项目里专门有一篇 fraud.md 讨论这个问题核心观点是不存在 100% 安全的许可证方案目标应该是让破解的成本高到没有动机去破解。防欺诈实践清单1. 把公钥直接嵌入 Java 源码而不是放成文件这是最重要的一条。不要通过 KeyPairReader.java 从文件加载公钥而是把公钥的字节数组以(byte)0x52, 0x53, 0x41...的形式硬编码进你的源代码。这样公钥会被编译进.class文件——攻击者想换公钥就必须同时反编译并修改你的业务代码类难度陡然上升。README 中给出的推荐用法就是// 公钥编码后直接写进应用 private final byte[] public_key { (byte)0x52, (byte)0x53, (byte)0x41, ... }; if (!license.isOK(public_key)) { return; // 签名校验失败拒绝运行 }注意自 3.0.0 起官方建议嵌入完整公钥而非仅嵌入公钥摘要值digest 校验 API 已不再支持这也是 fraud.md 中明确推荐的升级点。2. 若必须从文件加载公钥用摘要做二次校验某些场景下公钥确实需要动态加载此时可以预先计算公钥的SHA-512 摘要并写入源码加载公钥后比对摘要不一致立即拒绝即使文件被替换摘要对不上也会立刻暴露。可再对摘要字符串做轻度混淆提高替换成本。3. 用isOK()做签名完整性验证别只检查文件存在读取许可证文件本身不会检查签名——无论签名是否存在、是否被破坏LicenseReader 都会把它读进来。真正的验证在 License.java 的isOK()里取出被签名时的消息摘要算法signatureDigest特征通常是 SHA-512把许可证去掉签名特征后重新序列化为二进制计算摘要再用公钥解密签名里的密文摘要两者一致才返回true任何一处特征被改过比如把过期日期expiryDate往后挪一年校验必然失败。所以检查流程应该是读文件 →isOK(public_key)→ 校验通过后再使用特征值。4. 私钥永远不要出现在客户端环境KeyPairReader.java 的类注释说得很直白验证许可证的环境不应该有私钥。签名和发许可证是你软件提供方在自己环境里做的事客户端只做验证。一旦私钥泄露整个签名体系作废——请把它和源码分开保管。5. 用硬件绑定增加拷机成本但别做成硬拦截用 HardwareBinder.java 可以基于网卡 MAC、主机名、系统架构计算出一台机器的 UUID再把许可证绑定到该机器上。这样许可证拷到别的机器就失效了。官方推荐的姿势是警告而非强拒源码注释里有详细说明网卡坏了没时间换新许可证时强拒会把正常用户也挡在门外。建议检测到 UUID 不匹配时记录日志、提示用户而不是直接停机。6. 远程吊销把撤销权握在自己手里签名验证只保证许可证没被篡改但无法阻止你卖出去之后想收回。RevocableLicense.java 提供了解法在许可证里写入revocationUrlURL 中可以带${licenseId}占位符会自动替换成许可证 ID 或指纹运行时isRevoked()会去访问该 URL返回 200 表示未吊销返回 404 表示已吊销还支持服务器不可达时默认视为已吊销的严格模式简单理解在服务器上按 UUID 传一个空文件程序发现文件被删404就知道许可证被吊销了。7. 轻量场景SimpleLicense 的密钥保护如果你的产品只需要一个短许可证码如DCWI3U-6RDTB8-EBMPTJ-TVURQ7SimpleLicense.java 用秘密 用户值的 SHA-256 哈希生成码。它的防伪造关键在于secret 必须藏在代码里绝不能公开给用户。码本身不含任何用户信息是纯哈希截断无法逆向——但 secret 一旦泄露任何人都能批量生成合法码。一份可执行的自查清单#检查项参考1公钥是否嵌入.class而非 jar 内资源文件fraud.md2动态加载公钥时是否做了 SHA-512 摘要比对KeyPairReader.java3是否每次启动都调用isOK()验证签名License.java4私钥是否只存在于你的签发环境KeyPairReader.java5硬件绑定是否按警告优先实现HardwareBinder.java6是否配置了远程吊销 URLRevocableLicense.java最后说句实话fraud.md 开篇就提醒License3j 也可能被攻破没有绝对安全的许可证方案。真正的安全目标不是不可破解而是把破解成本推到合理收益之上同时通过电子签名拿到不可抵赖的证据链——谁篡改了许可证就无法狡辩以为是官方发的。按上面 7 条清单逐项落实你的 Java 产品就能获得相当扎实的防欺诈保护。【免费下载链接】License3jFree Licence Management Library项目地址: https://gitcode.com/gh_mirrors/li/License3j创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考