Java truelicense 实现License授权许可和验证

本文介绍了如何使用TrueLicense作为Java软件的授权管理工具,详细阐述了生成和验证证书的过程,包括使用Keytool生成密钥对、自定义KeyStoreParam、实现CustomLicenseManager进行额外校验、证书的安装与校验,以及解决在执行过程中遇到的问题。文章还提供了相关代码示例和参考资料。

前言

最近接到一个情况,公司平台有个授权使用的机制,之前负载这个事情的人走了,留在svn上的代码是无法通过授权的,所以让我看看什么情况

一、使用场景以及truelicense是什么

官网地址

TrueLicense是一个开源的证书管理引擎,使用场景:当项目交付给客户之后用签名来保证客户不能随意使用项目 默认校验了开始结束时间,可扩展增加mac地址校验等。 其中还有ftp的校验没有尝试,本demo详细介绍的是本地校验 license授权机制的原理: 生成密钥对,方法有很多。我们使用trueLicense来做软件产品的保护,我们主要使用它的LicenseManager类来生成证书文件、安装证书文件、验证证书文件.

二、原理

  1. 首先需要生成密钥对,方法有很多,JDK中提供的KeyTool即可生成。
  2. 授权者保留私钥,使用私钥对包含授权信息(如截止日期,MAC地址等)的license进行数字签名。
  3. 公钥交给使用者(放在验证的代码中使用),用于验证license是否符合使用条件。

三、使用Keytool命令生成密钥对

首先

Keytool 是一个Java 数据证书的管理工具 ,Keytool 将密钥(key)和证书(certificates)存在一个称为keystore的文件中 在keystore里,包含两种数据:
密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)
可信任的证书实体(trusted certificate entries)——只包含公钥

在接触代码前,我们先来大概熟悉下密钥生成的流程吧
Tips: 以下命令详细的参数需要可查看参考资料.4
1、首先要用KeyTool工具来生成私匙库:(-alias别名 –validity 3650表示10年有效)

keytool -genkey -alias privatekey -keystore privateKeys.store -validity 3650

这里密码我使用123456q
注意!!!默认的密码策略是6未数字与字母,如果不遵守会报错 第五节第二点的错
在这里插入图片描述
这个时候,会在打开命令行的地方创建出一个文件,privateKeys.store()
2、然后把私匙库内的证书导出到一个文件当中:

keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store

生成certfile.cer(证书),生成公钥库后就没什么用了

3、然后再把这个证书文件导入到公匙库:

keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store

生成 publicCerts.store

privateKeys.keystore:私钥,这个我们自己留着,不能泄露给别人。
publicCerts.keystore:公钥,这个给客户用的。在我们程序里面就是用他配合license进行授权信息的校验的。
certfile.cer:这个文件没啥用,可以删掉。

最后自行将生成文件privateKeys.store、publicCerts.store拷贝出来备用。

四、实现代码 - 证书生成

maven依赖

<!--        truelicense 依赖-->
        <!-- https://mvnrepository.com/artifact/de.schlichtherle.truelicense/truelicense-core -->
        <dependency>
            <groupId>de.schlichtherle.truelicense</groupId>
            <artifactId>truelicense-core</artifactId>
            <version>1.33</version>
        </dependency>

首先从整个流程上来讲,现在这步是证书生成,证书生成需要私钥库和证书参数
在这个引擎中,公/私钥库默认是存储在项目中的。** 但是,我们实际生产环境中,都是将配置文件等脱离项目部署的**,所以我们需要重写它获取公/私钥库的地方。
CustomKeyStoreParam.java

import de.schlichtherle.license.AbstractKeyStoreParam;
import org.springframework.util.ResourceUtils;

import java.io.*;

/**
 * 自定义KeyStoreParam,用于将公私钥存储文件存放到其他磁盘位置而不是项目中。现场使用的时候公钥大部分都不会放在项目中的
 */
public class CustomKeyStoreParam extends AbstractKeyStoreParam {
   
   

    /**
     * 公钥/私钥在磁盘上的存储路径
     */
    private String storePath;
    private String alias;
    private String storePwd;
    private String keyPwd;

    public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePwd, String keyPwd) {
   
   
        super(clazz, resource);
        this.storePath = resource;
        this.alias = alias;
        this.storePwd = storePwd;
        this.keyPwd = keyPwd;
    }


    @Override
    public String getAlias() {
   
   
        return alias;
    }

    @Override
    public String getStorePwd() {
   
   
        return storePwd;
    }

    @Override
    public String getKeyPwd() {
   
   
        return keyPwd;
    }

    /**
     * AbstractKeyStoreParam里面的getStream()方法默认文件是存储的项目中。
     * 用于将公私钥存储文件存放到其他磁盘位置而不是项目中
     */
    @Override
    public InputStream getStream() throws IOException {
   
   
//        return new FileInputStream(new File(storePath));
        File file = ResourceUtils.getFile(storePath);
        if (file.exists()) {
   
   
            return new FileInputStream(file);
        } else {
   
   
            throw new FileNotFoundException(storePath);
        }
    }
}

证书参数可以用配置文件配置,也可以写成类,这个方法用的就是类的方式

License.java

import cn.genm.license.dto.LicenseExtraModel;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * License生成类需要的参数
 */
@Data
public class License implements Serializable {
   
   

    private static final long serialVersionUID = -7793154252684580872L;
    /**
     * 证书subject
     */
    private String subject;

    /**
     * 私钥别称
     */
    private String privateAlias;

    /**
     * 私钥密码(需要妥善保管,不能让使用者知道)
     */
    private String keyPass;

    /**
     * 访问私钥库的密码
     */
    private String storePass;

    /**
     * 证书生成路径
     */
    private String licensePath;

    /**
     * 私钥库存储路径
     */
    private String privateKeysStorePath;

    /**
     * 证书生效时间
     */
    private Date issuedTime = new Date();

    /**
     * 证书失效时间
     */
    private Date expiryTime;

    /**
     * 用户类型
     */
    private String consumerType = "user";

    /**
     * 用户数量
     */
    private Integer consumerAmount = 1;

    /**
     * 描述信息
     */
    private String description = "";

    /**
     * 额外的服务器硬件校验信息
     */
    private LicenseExtraModel licenseExtraModel;
}

其中的扩展参数类


/**
 * 自定义需要校验的License参数,可以增加一些额外需要校验的参数,比如项目信息,ip地址信息等等,待完善
 */
public class LicenseExtraModel {
   
   

    // 这里可以添加一些往外的自定义信息,比如我们可以增加项目验证,客户电脑sn码的验证等等

}

由于引擎本身默认只验证了有效期,当我们需要自定义一个继承于LicenseManager的自定义证书管理器。
额外的信息的校验可以加在validate()方法里

CustomLicenseManager.java

import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
import de.schlichtherle.xml.XMLConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.<
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值