赞
踩
技术:apache-maven-3.3.9 +jdk1.8.0_102
运行环境:ideaIC-2020.1.3 + apache-maven-3.3.9+ jdk1.8.0_102
家精品内容,核心代码解析
多代码预警~觉着有帮助的别忘了给小普点赞!
作者:陈鸿姣 编辑:Carol
01 概述
TrueLicense是一个开源的证书管理引擎,使用trueLicense来做软件产品的保护,基于TrueLicense实现产品License验证功能,给产品加上License验证功能,进行试用期授权,在试用期过后,产品不再可用。
02 使用场景
小普看来,当项目交付给客户之后用签名来保证客户不能随意使用项目,TrueLicense默认校验了开始结束时间,可扩展增加mac地址校验等。
因此,小普详细介绍的是本地校验 license授权机制的原理以及主要使用TrueLicense的LicenseManager类来生成证书文件、安装证书文件、验证证书文件等。
03 license授权机制的原理
原理如下:
(1)生成密钥对,包含私钥和公钥。(2)授权者保留私钥,使用私钥对授权信息诸如使用截止日期,mac 地址等内容生成 license 签名证书。(3)公钥给使用者,放在代码中使用,用于验证 license 签名证书是否符合使用条件。
04 使用KeyTool生成密匙库
使用jdk自带的KeyTool工具生成密钥库,这里使用的jdk版本是jdk1.8.0_102。首先我们找到KeyTool所在的目录,截图如下:
可以看到Windowscmd窗口如下:
生成密码库的步骤如下:
(1)生成密钥库
keytool -genkeypair-keysize 1024 -validity 3650-alias
"privateKey" -keystore "privateKeys.keystore"
(2)生成证书文件
keytool -exportcert -alias "privateKey" -keystore "privateKeys.keystore" -
file "certfile.cer"
(3)生成公钥库
keytool -import -alias "publicCert" -file "certfile.cer" -keystore
"publicCerts.keystore"
最后在D:\work soft\java\jdk1.8.0_102\jre\bin目录下:看到以下三个文件:
privateKeys.keystore(私钥)提供给生成证书使用
publicCerts. keystore(公钥)提供给证书认证使用
certfile.cer后续步骤用不到,可以删除。
05 Springboot+TrueLicense证书生成和认证
(1)引入jar包:
首先,我们需要引入 truelicense 的 jar 包,用于实现我们的证书管理。
(2)证书生成步骤以及核心实现代码
① 校验自定义的License参数。首先,创建自定义的可被允许的服务器硬件信息的实体类(如果校验其他参数,可自行补充).备注:如果只需要检验文件的生效和过期时间无需创建此类。
/** * @author chenhongjiao */ @Data public class LicenseCheckModelimplements Serializable { private static final long serialVersionUID = 8600137500316662317L; /** * 可被允许的IP地址 */ private List<String> ipAddress; /** * 可被允许的MAC地址 */ private List<String> macAddress; /** * 可被允许的CPU序列号 */ private String cpuSerial; /** * 可被允许的主板序列号 */ private String mainBoardSerial; }
② 其次,创建License生成需要的参数实体类
/** * @author chenhongjiao */ @Data public class LicenseCreatorParam 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; /** * 证书生效时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date issuedTime = new Date(); /** * 证书失效时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date expiryTime; /** * 用户类型 */ private String consumerType = "user"; /** * 用户数量 */ private Integer consumerAmount = 1; /** * 描述信息 */ private String description = ""; /** * 额外的服务器硬件校验信息,无需额外校验可去掉 */ private LicenseCheckModel licenseCheckModel; }
③添加抽象类AbstractServerInfos,用户获取服务器的硬件信息。
(备注:根据需要选择,无需额外校验可去掉)
@Slf4j
public abstract class AbstractServerInfos {
/** * 组装需要额外校验的License参数 * @author chenhongjiao * @date 2021/03/26 14:23 * @since 1.0.0 * @return LicenseCheckModel */ public LicenseCheckModel getServerInfos(){ LicenseCheckModel result = new LicenseCheckModel(); try { result.setIpAddress(this.getIpAddress()); result.setMacAddress(this.getMacAddress()); result.setCpuSerial(this.getCPUSerial()); result.setMainBoardSerial(this.getMainBoardSerial()); }catch (Exception e){ log.error("获取服务器硬件信息失败",e); } return result; } /** * 获取IP地址 * @author chenhongjiao * @date 2021/03/26 11:32 * @since 1.0.0 * @return java.util.List<java.lang.String> */ protected abstract List<String> getIpAddress() throws Exception; /** * 获取Mac地址 * @author chenhongjiao * @date 2021/03/26 11:32 * @since 1.0.0 * @return java.util.List<java.lang.String> */ protected abstract List<String> getMacAddress() throws Exception; /** * 获取CPU序列号 * @author chenhongjiao * @date 2021/03/26 11:35 * @since 1.0.0 * @return java.lang.String */ protected abstract String getCPUSerial() throws Exception; /** * 获取主板序列号 * @author chenhongjiao * @date 2021/03/26 11:35 * @since 1.0.0 * @return java.lang.String */ protected abstract String getMainBoardSerial() throws Exception; /** * 获取当前服务器所有符合条件的InetAddress * @author chenhongjiao * @date 2021/03/26 17:38 * @since 1.0.0 * @return java.util.List<java.net.InetAddress> */ protected List<InetAddress> getLocalAllInetAddress() throws Exception { List<InetAddress> result = new ArrayList<>(4); // 遍历所有的网络接口 for (Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); networkInterfaces.hasMoreElements(); ) { NetworkInterface iface = (NetworkInterface) networkInterfaces.nextElement(); // 在所有的接口下再遍历IP for (Enumeration inetAddresses = iface.getInetAddresses(); inetAddresses.hasMoreElements(); ) { InetAddress inetAddr = (InetAddress) inetAddresses.nextElement(); //排除LoopbackAddress、SiteLocalAddress、LinkLocalAddress、MulticastAddress类型的IP地址 if(!inetAddr.isLoopbackAddress() && !inetAddr.isLinkLocalAddress() && !inetAddr.isMulticastAddress()){ result.add(inetAddr); } } } return result; } /** * 获取某个网络接口的Mac地址 * @author chenhongjiao *
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。