热门课程

免费试听

上课方式

开班时间

当前位置: 首页 -   文章 -   新闻动态 -   正文

Springboot实现软件License授权认证

知了堂姐
2024-07-09 11:12:24
0

在我们做系统级框架的时候,我们要一定程度上考虑系统的使用版权,不能随便一个人拿去在任何环境都能用,所以我们需要给我们系统做一个授权认证机制,只有上传了我们下发的lic文件并验证通过,才能正常使用。

一、Smart-license简介

smart-license 是一款用于安全加固的开源项目。主要服务于非开源产品、商业软件、具备试用功能的付费软件等,为软件提供授权制的使用方式。

1. License,通过 smart-license 生成的授权文件,导入至要授权使用的软件产品中。

2. 源数据,需要进行 License 加工处理的基础数据。例如,将软件产品运行的配置文件作为源数据,经由 smart-license 授权处理后生成 License 文件。

3. License源文件,生成 License 的同时,创建一份文件用于记录:源数据、授权时间、过期时间、秘钥对等信息。由软件授权方持有,当客户遗失 License 文件之后可以根据License源文件重新生成 License。

二、什么是 License

license 翻译为许可证。理解为协议或版权声明,违反协议的后果就是商业纠纷。用原创作品类比,我发布这篇文章时声明了原创,别人如果要转载这篇文章,要经过我允许,否则就侵犯了我的权益。当然文章的版权与软件版权还是不一样的,不做过多比较。

适用场景:

  • 非开源产品、商业软件、收费软件。
  • 限制产品的传播性,每个客户拥有专属 License。
  • 同一款软件发行包根据 License 的不同提供不同的服务能力。
  • 限定软件授权时效。

产品特色:

  • 开源:代码完全公开,License的生成原理是透明的。
  • 易用:提供二进制包,直接基于命令行生成 License。
  • 安全:生成的 License 在一定程度上具备防篡改能力,破解难度大。
  • 安全加固:采用非对称加密方式对 License源数据 进行预处理,防止伪造License。

三、License运行流程

四、License申请流程

五、找回License

六、使用方式

下载smart-license.tar.gz包,解压。

进入bin目录执行以下命令,例如:./license.sh 1d HelloWorld。

1d:表示授权效期1天,即一天后该License便过期。支持的效期格式包括: h,1h:1小时;2h:2小时 d;1d:1天;10d:10天;1y:1年;2y:2年;HelloWorld:表示待加密的license内容。 实际场景下可以通过license授权不同的产品功能和有效期,例如:./license.sh 1y features_1:on;features_2:off; 如果待授权的license内容为文件,可以采用同样的命令,例如:./license.sh 1y config.properties。

执行成功后,会在当前目录下生成 License:license.txt以及 License源文件:source.txt。 注意:license.txt是提供给客户的授权文件;而source.txt是由软件提供方持有,其中包含加密私钥,需要妥善保管。

七、项目集成

  • 引入Maven依赖

  org.smartboot.license
  license-client
  1.0.3

  • 载入License。如若License已过期,则会触发异常。
public class LicenseTest {
  public static void main(String[] args) throws Exception {
      File file=new File("license.txt");
      License license = new License();
      LicenseEntity licenseEntity=license.loadLicense(file);
      System.out.println(new String(licenseEntity.getData()));
  }
}
  • 获取licenseEntity并以此配置启动软件。
  • 还原license。
  1. 进入bin目录执行以下命令,例如:./license_revert.sh source.txt。
  2. 执行成功后会在当前目录下生成License文件license_revert.txt。

简单方便,几行代码放在启动方法里校验,也可以加注在拦截器里。

一个简单方便的授权方式,只需以上几步就可集成到boot项目中去啦

说了这么多,再演示下代码吧。

1.生成机器码

我们首先要做的就是对软件部署的环境的唯一性进行限制,这里使用的是macadderss,当然你也可以换成cpu序列编号,并无太大影响,先上代码。

private static String getMac() {
        try {
            Enumeration el = NetworkInterface
                    .getNetworkInterfaces();
            while (el.hasMoreElements()) {
                byte[] mac = el.nextElement().getHardwareAddress();
                if (mac == null)
                    continue;
                String hexstr = bytesToHexString(mac);
                return getSplitString(hexstr, "-", 2).toUpperCase();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return null;
    } 
 
public static String getMachineCode() throws Exception{
        Set result = new HashSet<>();
        String mac = getMac();
        result.add(mac);
        Properties props = System.getProperties();
        String javaVersion = props.getProperty("java.version");
        result.add(javaVersion);
        String javaVMVersion = props.getProperty("java.vm.version");
        result.add(javaVMVersion);
        String osVersion = props.getProperty("os.version");
        result.add(osVersion);
        String code = Encrpt.GetMD5Code(result.toString());
        return getSplitString(code, "-", 4);
 
    }

这里进行的操作是取出机器码,与java版本、jvm、操作系统参数进行混合,并进行MD5操作。

2.进行lic文件的生成

授权证书主要包含三个要素:机器码、是否永久有效标识、证书时效。我们会将这些数据写入文本中并进行加密处理,看下生成证书的代码。

public static void getLicense(String isNoTimeLimit, String licenseLimit, String machineCode, String licensePath, String priavateKeyPath) throws Exception{
        String[] liccontent = {
                "LICENSEID=yanpeng19940119@gmail.com",
                "LICENSENAME=YBLOG使用证书",
                MessageFormat.format("LICENSETYPE={0}",isNoTimeLimit),
                MessageFormat.format("EXPIREDAY={0}",licenseLimit), //日期采用yyyy-MM-dd日期格式
                MessageFormat.format("MACHINECODE={0}",machineCode),
                ""
        };
 
        //将lic内容进行混合签名并写入内容
        StringBuilder sign = new StringBuilder();
        for(String item:liccontent){
            sign.append(item+"yblog");
        }
        liccontent[5] = MessageFormat.format("LICENSESIGN={0}",Encrpt.GetMD5Code(sign.toString()));
        FileUtil.createFileAndWriteLines(licensePath,liccontent);
        //将写入的内容整体加密替换
        String filecontent =FileUtil.readFileToString(licensePath);
        String encrptfilecontent = Encrpt.EncriptWRSA_Pri(filecontent,priavateKeyPath);
        File file = new File(licensePath);
        file.delete();
        FileUtil.createFile(licensePath,encrptfilecontent);

最后在验证lic,我们会在系统中注册一个拦截器,未通过系统授权认证会自动跳转到lic文件上传界面,springboot接收文件与常规java有一些不同,使用的MultipartFile对象,会获取到上传文件的数组,进行操作。

我们就可以通过系统内置的公钥对lic文件的机器码,授权时间进行验证,确定是否能正常访问系统。

大家都在看

知了堂全国招募体验官招募的UI实战需求

2024-07-09 浏览次数:0

程序员月薪8000,丢人吗?

2024-07-09 浏览次数:0

CentOs7 Redis6.0.6安装

2024-07-09 浏览次数:0

前端css的引用方式有哪几种?css的三种引用方...

2024-07-09 浏览次数:0

路由的作用和工作原理是什么?如何理解路由原理?

2024-07-09 浏览次数:0

网络安全学哪些课程?网络安全的秘密宝库

2024-07-09 浏览次数:0
最新资讯
Springboot实现软件L... 在我们做系统级框架的时候,我们要一定程度上考虑系统的使用版权,不能随便一个人拿去在任何环境都能用,所...
Springboot实现软件L... 在我们做系统级框架的时候,我们要一定程度上考虑系统的使用版权,不能随便一个人拿去在任何环境都能用,所...