Java truelicense 实现License授权许可和验证
文章目录
前言
一、使用场景以及truelicense是什么
二、原理
三、使用Keytool命令生成密钥对
四、实现代码 - 证书生成
五、测试 - 证书生成
六、代码实现 - 证书安装和校验
七、测试 - 证书的安装和校验
八、执行代码期间遇到的问题
九、参考资料
前言
最近接到一个情况,公司平台有个授权使用的机制,之前负载这个事情的人走了,留在svn上的代码是无法通过授权的,所以让我看看什么情况
一、使用场景以及truelicense是什么
官网地址
TrueLicense是一个开源的证书管理引擎,使用场景:当项目交付给客户之后用签名来保证客户不能随意使用项目 默认校验了开始结束时间,可扩展增加mac地址校验等。 其中还有ftp的校验没有尝试,本demo详细介绍的是本地校验 license授权机制的原理: 生成密钥对,方法有很多。我们使用trueLicense来做软件产品的保护,我们主要使用它的LicenseManager类来生成证书文件、安装证书文件、验证证书文件.
二、原理
首先需要生成密钥对,方法有很多,JDK中提供的KeyTool即可生成。
授权者保留私钥,使用私钥对包含授权信息(如截止日期,MAC地址等)的license进行数字签名。
公钥交给使用者(放在验证的代码中使用),用于验证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依赖
首先从整个流程上来讲,现在这步是证书生成,证书生成需要私钥库和证书参数
在这个引擎中,公/私钥库默认是存储在项目中的。** 但是,我们实际生产环境中,都是将配置文件等脱离项目部署的**,所以我们需要重写它获取公/私钥库的地方。
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