V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wenbingkun
V2EX  ›  Java

Java 如何实现软件许可证功能?

  •  
  •   wenbingkun · 2023-08-30 10:45:10 +08:00 · 4446 次点击
    这是一个创建于 462 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我在开发一个基于 Spring Boot 和 Vue 的前后端分离项目,现在面临一个需求:为软件添加许可证功能,从而区分试用版、正式版等,并通过激活码或许可证文件进行软件激活。

    目前想到的实现思路:

    后端( Spring Boot ):用于生成、验证和存储许可证信息。
    前端( Vue.js ):用于让用户输入激活码、上传许可证文件或显示激活状态等。

    还有一些疑虑:

    许可证的验证应该在哪一端进行?只在后端进行还是两端都需要?
    如何确保前端和后端的许可证验证同步?
    对于前后端分离的项目,有没有哪些特定的安全性问题需要注意?
    是否有推荐的库或工具,特别是适合这种架构的?

    如果有相关经验或建议,希望能与我分享,感谢!
    29 条回复    2023-09-07 17:12:27 +08:00
    byasm32
        1
    byasm32  
       2023-08-30 10:52:51 +08:00
    问 ai 更快获得解决方案。。
    darling19961030
        2
    darling19961030  
       2023-08-30 10:58:38 +08:00
    1. 放后端,登录的时候做授权验证,过不了都登不上所以前端不用做
    2. 没明白啥意思,但放登录的话应该能解决你这个疑问
    3. 太宽泛
    4. 估计 github 上有相关库吧

    说说我遇到的问题,就是你做 license 验证肯定要跟硬件信息绑定,但如果你是容器化部署的话就不太好处理了,但也有方案比如 ssh 到宿主机获取信息,但感觉不是个好方法。
    cooltechbs
        3
    cooltechbs  
       2023-08-30 10:58:40 +08:00
    前端验个格式就行(类似身份证号最后一位那种校验和机制) 后端检查授权真实性、关联设备
    因为前后端验证任务不同,也不用保持同步
    后端应该还好,前端需要防破(防止绕过验证机制直接进入已激活状态),比如代码混淆(指令加花),但是这只能延缓被破解的进度,不能彻底防止破解(就是一猫鼠游戏)


    利益相关:没有相关建议,上面的思路都是自己瞎想的,看看能不能引出玉来
    cooltechbs
        4
    cooltechbs  
       2023-08-30 10:59:33 +08:00
    没有相关建议 ==> 没有相关经验。。。
    V2EX 的回复连一分钟的修改窗口期都不给吗
    janus77
        5
    janus77  
       2023-08-30 11:04:39 +08:00
    看你需求是什么形态,激活码模式?登录会员账号的模式?订阅模式?是 pc 端软件还是移动端?是否能离线使用?是否需要试用版?续期如何解决?
    验证我觉得应该是丢给后端验证了
    一般思路是前端生成一个唯一特征的信息丢给后端,再加密,再给这个加密信息附上许可有效相关的信息,最后生成许可证
    wenbingkun
        6
    wenbingkun  
    OP
       2023-08-30 11:08:38 +08:00
    @janus77 激活码模式,有试用版和正式版,激活后可离线使用,网页应用
    wenbingkun
        7
    wenbingkun  
    OP
       2023-08-30 11:11:22 +08:00
    @darling19961030 目前是容器化部署的,可能不太好获取宿主机信息,开源库找到了 TrueLicense
    obed
        8
    obed  
       2023-08-30 11:23:31 +08:00
    这边一个项目的做法,只后端,op 可以参考一下。
    一个专门的 License 应用,用于生产 License code ,正式应用这边加了个拦截器,验证这个 License code 。
    License code 是一个项目标志加一个时间戳用 rsa 的私钥加密生成的,应用拦截器这边,获取数据库和应用容器的时间,判断是否一致,不一致直接拦截,然后用公钥解密,判断项目标志与配置的是否一致,时间是否有效。
    不过这个东西就是防君子不防小人。
    registerrr
        9
    registerrr  
       2023-08-30 11:27:33 +08:00
    @obed 确实是防君子不防小人。反编译 jar 包,直接找你验证代码,注掉替换,就免费了。不过反过来说,至少比敞开着门强一点。
    corcre
        10
    corcre  
       2023-08-30 11:42:13 +08:00
    写了一点想法, 然后发现是个网页应用, 所以这其实是一个纯前端的应用, 脱离后端也能运行?后端只负责验证?
    在我的印象中纯前端验证就约等于没有验证, 或者说防君子不防小人...
    aapeli
        11
    aapeli  
       2023-08-30 11:47:08 +08:00
    @wenbingkun 考虑 License 和宿主机的主板 ID 进行绑定 linux 下使用命令 dmidecode -t system 可以拿到主板相关的信息, 如果在容器内访问可以参考文档: https://stackoverflow.com/questions/54068234/cant-run-dmidecode-on-docker-container


    一旦 License 和主板 ID 绑定(可以限制这个 License 可以用于多少台机子),如果激活完成后复制到其他机子就没办法使用.

    关于 License 建议放后端
    aapeli
        12
    aapeli  
       2023-08-30 11:48:18 +08:00
    starxg
        13
    starxg  
       2023-08-30 11:59:24 +08:00
    使用 RSA 验签吧,废话不多说,直接上代码。

    ```java
    public static void main(String[] args) throws Exception {
    final KeyPair pair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
    System.out.println(Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded()));
    System.out.println(Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()));

    // 采用密文公开+签名的方式
    byte[] signature;
    byte[] license = "{\"username\":\"张三\"}".getBytes(StandardCharsets.UTF_8);

    // 私钥得到签名
    {
    Signature signer = Signature.getInstance("SHA1withRSA");
    signer.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(pair.getPrivate().getEncoded())));
    signer.update(license);
    signature = signer.sign();
    }

    // 公钥验证签名
    {
    Signature signer = Signature.getInstance("SHA1withRSA");
    signer.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pair.getPublic().getEncoded())));
    signer.update(license);
    System.out.println(signer.verify(signature));
    }
    }
    ```

    在 java 里面,无论你是什么加密都可以通过 javaagnet 给你搞掉,所以防君子不小人。
    Daniel17
        14
    Daniel17  
       2023-08-30 12:03:08 +08:00
    v 站没有渲染代码块的功能吗
    gps949
        15
    gps949  
       2023-08-30 13:11:13 +08:00
    要想绝对高强度不可能被破解(防君子也防小人),就试试使用 TPM 吧
    https://patents.google.com/patent/WO2012149717A1/zh
    satanandroid
        16
    satanandroid  
       2023-08-30 13:32:00 +08:00
    在你的基于 Spring Boot 和 Vue 的前后端分离项目中添加许可证功能是可行的。下面是一些实现思路和建议:

    后端( Spring Boot ):

    实现许可证生成:编写逻辑来生成许可证,可以包括许可证的格式、加密算法等。
    许可证验证:在后端进行许可证的验证,确保传递的激活码或许可证文件是有效的。
    许可证信息存储:将许可证相关信息存储在后端,可以使用数据库或其他持久化方式。
    前端( Vue.js ):

    用户界面:设计一个用户界面,用于用户输入激活码、上传许可证文件或显示激活状态等。
    与后端通信:通过接口与后端进行通信,包括发送激活码或许可证文件并接收验证结果等。
    关于你的疑虑:

    许可证的验证可以在后端进行,因为后端可以更可靠地处理验证逻辑和密钥存储。前端可以发送激活码或许可证文件到后端进行验证。
    为了确保前后端的许可证验证同步,可以在后端实现一个许可证验证的接口,前端通过调用该接口进行验证,并根据验证结果做出相应的处理。
    对于前后端分离的项目,确保接口安全性是重要的,可以使用身份验证和授权机制来保护许可证接口。另外,确保许可证相关的敏感信息在传输过程中进行加密保护。
    关于库或工具,Spring Security 是一个流行的安全框架,可以用于后端的身份验证和授权。在前端方面,可以考虑使用 Vue Router 和 Vuex 来管理路由和状态。
    总之,许可证功能的实现需要在后端生成和验证许可证,前端提供用户界面,并与后端进行通信。确保接口的安全性,并选择适合你的项目的安全框架和库。
    Dream11
        17
    Dream11  
       2023-08-30 14:00:00 +08:00
    我现在用的 `truelicense-core` 已实现效果,可以去了解下
    dog82
        18
    dog82  
       2023-08-30 15:45:16 +08:00
    这个问题问的好!!!
    wenbingkun
        19
    wenbingkun  
    OP
       2023-08-30 15:57:55 +08:00
    @satanandroid chatgpt 是吧😂
    wenbingkun
        20
    wenbingkun  
    OP
       2023-08-30 15:58:23 +08:00
    @starxg 谢谢,我试试看
    wenbingkun
        21
    wenbingkun  
    OP
       2023-08-30 15:59:00 +08:00
    @aapeli 好的,谢谢
    wenbingkun
        22
    wenbingkun  
    OP
       2023-08-30 15:59:35 +08:00
    @Dream11 正在看 TrueLicense 的文档
    mmdsun
        23
    mmdsun  
       2023-08-30 17:39:50 +08:00
    这个是怎么出售的的?后端也卖给别人吗?这种很难防住的。
    k9990009
        24
    k9990009  
       2023-08-30 19:52:18 +08:00 via Android
    用 classfinal 把代码加密下
    lqw3030
        25
    lqw3030  
       2023-08-30 20:06:15 +08:00
    项目价值确实高的话,就不自己瞎倒腾,直接上 codemeter ,自己倒腾参照 IDEA,年年有破解。。
    dode
        26
    dode  
       2023-08-30 20:36:20 +08:00
    检查环境,定期连接互联网服务器核查续期
    xianzhe
        27
    xianzhe  
       2023-08-31 07:49:26 +08:00 via Android
    javaagent 在那,很难防得住,当然基本的 license 检查和代码混淆还是要做的,另外还要考虑多破解的检查以支持法务的介入。这东西往难了做能做的很复杂,可以搞专门的加密狗一样的东西,甚至必须用专有定制的硬件,还是要综合考虑成本值不值
    tramm
        28
    tramm  
       2023-08-31 08:46:55 +08:00
    参考 J2eeFast 这个项目看看呢
    t298
        29
    t298  
       2023-09-07 17:12:27 +08:00
    使用 TrueLicense ,也是在 docker 里部署的,获取 mac ,ip 和 cpu 信息好像都有点问题。目前只搞定了时间的验证,因为是部署是内网的,那是不是只要说改了服务器时间,那这个验证就失效了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3512 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:49 · PVG 18:49 · LAX 02:49 · JFK 05:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.