Java 如何实现软件许可证功能? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wenbingkun
V2EX    Java

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

  •  
  •   wenbingkun 2023-08-30 10:45:10 +08:00 5227 次点击
    这是一个创建于 773 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我在开发一个基于 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 的回复连一分钟的修改窗口期都不给吗
    rb6221
        5
    rb6221  
       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   div class="badges">
    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 把代码加密下
    xyooyx
        25
    xyooyx  
       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     Solana     2610 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 14:51 PVG 22:51 LAX 07:51 JFK 10:51
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86