本来的目的是尝试给项目加一个license控制用户的使用时间等信息,在网上查到可以使用TrueLicense工具生成License,并进行验证,参考网上资源:javaEE防盗版-License开发 进行的些许调整,如下:
先梳理一下整体的步骤:
1.需要使用keytool工具创建密钥库、密钥、公钥库、公钥、证书等文件
2.授权方生成license文件:trueLicense使用上述生成的密钥库、密钥生成license.lic文件
3.使用方验证license文件:trueLicense使用上述生成的公钥库、公钥验证license.lic文件
开始正文:
1.使用keytool工具创建密钥库、密钥、公钥库、公钥、证书
请切换到一个你想要存放文件的目录,此处为D:\keyTest文件夹,生成的文件都在这个文件夹下面
1.1 生成密钥库和密钥
keytool -genkey -alias myPrivateKey01 -keystore myPrivateKeyStore.store -validity 20
-alias 表示密钥的别名
-keystore 表示当前密钥属于哪个密钥库
-validity 表示有效期(单位:天)
注意截图处有两处需要输入密码:
第一处输入的是密钥库的密码;第二处输入的是密钥库中密钥的密码(这个密码需要保密哦!)
1.2 导出密钥库内密钥的证书
keytool -export -alias myPrivateKey01 -file certfile01.cer -keystore myPrivateKeyStore.store
-file 表示导出的文件
1.3 把证书导入到公钥库中,创建公钥库和公钥
keytool -import -alias myPublicCert01 -file certfile01.cer -keystore myPublicCerts01.store
此处需要设置一个公钥库的密码,经过调试测试验证,此处的公钥库密码需要和第一步中的密钥库的密码保持一致
第一步完毕
第二步开始之前需要添加jar包,依赖关系如下:
<!-- https://mvnrepository.com/artifact/de.schlichtherle.truelicense/truelicense-core -->
<dependency>
<groupId>de.schlichtherle.truelicense</groupId>
<artifactId>truelicense-core</artifactId>
<version>1.33</version>
</dependency>
<!-- https://mvnrepository.com/artifact/de.schlichtherle.truelicense/truelicense-xml -->
<dependency>
<groupId>de.schlichtherle.truelicense</groupId>
<artifactId>truelicense-xml</artifactId>
<version>1.33</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/de.schlichtherle.truelicense/truelicense-swing -->
<dependency>
<groupId>de.schlichtherle.truelicense</groupId>
<artifactId>truelicense-swing</artifactId>
<version>1.33</version>
</dependency>
2.授权方生成license文件
代码结构如下图:
LicenseManagerHolder.java
package com.iss.license.generate;
import de.schlichtherle.license.LicenseManager;
import de.schlichtherle.license.LicenseParam;
/**
*
* @author qianwangn
*
*/
public class LicenseManagerHolder {
private static LicenseManager licenseManager;
private LicenseManagerHolder(){}
public static synchronized LicenseManager getLicenseManager(LicenseParam param){
if(licenseManager == null){
licenseManager = new LicenseManager(param);
}
return licenseManager;
}
}
LicenseMake.java
package com.iss.license.generate;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Properties;
import java.util.prefs.Preferences;
import javax.security.auth.x500.X500Principal;
import de.schlichtherle.license.CipherParam;
import de.schlichtherle.license.DefaultCipherParam;
import de.schlichtherle.license.DefaultKeyStoreParam;
import de.schlichtherle.license.DefaultLicenseParam;
import de.schlichtherle.license.KeyStoreParam;
import de.schlichtherle.license.LicenseContent;
import de.schlichtherle.license.LicenseManager;
import de.schlichtherle.license.LicenseParam;
public class LicenseMake {
private String licPath;
private String issued;
private String notBefore;
private String notAfter;
private String consumerType;
private int consumerAmount;
private String info;
/**
* 私钥的别名
*/
private String priAlias;
/**
* 该密码生成密钥对的密码
*/
private String privateKeyPwd;
/**
* 使用keytool生成密钥对时设置的密钥库的访问密码
*/
private String keyStorePwd;
private String subject;
private String priPath;
/**
* X500Principal是一个证书文件的固有格式
*/
private final static X500Principal DEFAULTHOLDERANDISSUER =
new X500Principal("CN=wq,OU=iss,O=iss,L=bj,ST=bj,C=china");
public LicenseMake(){}
public LicenseMake(String confPath){
initParam(confPath);
}
/**
* 读取属性文件
* @param confPath
*/
public void initParam(String confPath){
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream(confPath);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
priAlias = prop.getProperty("private.key.alias");
privateKeyPwd = prop.getProperty("private.key.pwd");
keyStorePwd = prop.getProperty("key.store.pwd");
subject = prop.getProperty("subject");
priPath = prop.getProperty("priPath");
licPath = prop.getProperty("licPath");
//license content
issued = prop.getProperty("issuedTime");
notBefore = prop.getProperty("notBefore");
notAfter = prop.getProperty("notAfter");
consumerType = prop.getProperty("consumerType");
consumerAmount = Integer.valueOf(prop.getProperty("consumerAmount"));
info = prop.getProperty("info");
}
private LicenseParam initLicenseParam(){
Class<LicenseMake> clazz = LicenseMake.class;
Preferences pre = Preferences.userNodeForPackage(clazz);
//设置对证书内容加密的对称密码
CipherParam cipherParam = new DefaultCipherParam(keyStorePwd);
/**
* clazz 从哪个类Class.getResource()获得密钥库
* priPath 从哪个类Class.getResource()获得密钥库
* priAlias 密钥库的别名
* keystorePwd 密钥库存储密码
* privateKeyPwd 密钥库密码
*/
KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(
clazz,priPath,priAlias,keyStorePwd,privateKeyPwd);
//返回生成证书时需要的参数
LicenseParam licenseParam = new DefaultLicenseParam(
subject,pre,privateStoreParam,cipherParam);
return licenseParam;
}
public LicenseContent buildLicenseContent() throws ParseException{
LicenseContent content = new LicenseContent();
SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
content.setSubject(subject);
content.setConsumerAmount(consumerAmount);
content.setConsumerType(consumerType);
content.setHolder(DEFAULTHOLDERANDISSUER);
content.setIssuer(DEFAULTHOLDERANDISSUER);
content.setIssued(formate.parse(issued));
content.setNotBefore(formate.parse(notBefore));
content.setNotAfter(formate.parse(notAfter));
content.setInfo(info);
content.setExtra(new Object());
return content;
}
public void create(){
try {
LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(initLicenseParam());
LicenseContent content = buildLicenseContent();
licenseManager.store(content, new File(licPath));
System.out.println("证书发布成功");
} catch (ParseException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
参数配置文件:licenseMakeConf.properties
##########common parameters###########
#密钥的别名
private.key.alias=myPrivateKey01
#密钥的密码(应妥善保管,不能被使用者知道)
private.key.pwd=wq@123@01
#密钥库的密码
key.store.pwd=wq@123
#项目唯一识别码
subject=happy
#生成的license文件的位置,绝对地址
licPath=D:/eclipse_mars_workspace/LicenseTest/license.lic
#密钥库的地址,相对路径,此在类路径下(就是我们第一步中生成的密钥库文件,拷贝到类路径下面即可)
priPath=/myPrivateKeyStore.store
##########license content###########
#发布日期
issuedTime=2018-03-29
#开始日期
notBefore=2018-03-29
#截止日期
notAfter=2018-03-30
#consumerType
consumerType=user
#ConsumerAmount
consumerAmount=1
#info
info=this is a license
测试代码:Test.java
package com.iss.license.generate;
public class Test {
public static void main(String[] args) throws Exception
{
LicenseMake clicense=new LicenseMake("licenseMakeConf.properties");
clicense.create();
}
}
注意:一定要将第一步生成的myPrivateKeyStore.store密钥库文件拷贝到类路径下
如何获取类路径:在Test.java中可以查看一下
String path = Test.class.getResource("/").getPath();
System.out.println("path="+path);
3. 使用方验证license文件
首先将第一步中生成的公钥库文件(myPublicCerts01.store)拷贝到类路径中
代码结构如图:verify包
LicenseVertify.java
package com.iss.license.verify;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.prefs.Preferences;
import com.iss.license.generate.LicenseManagerHolder;
import de.schlichtherle.license.CipherParam;
import de.schlichtherle.license.DefaultCipherParam;
import de.schlichtherle.license.DefaultKeyStoreParam;
import de.schlichtherle.license.DefaultLicenseParam;
import de.schlichtherle.license.KeyStoreParam;
import de.schlichtherle.license.LicenseContentException;
import de.schlichtherle.license.LicenseManager;
import de.schlichtherle.license.LicenseParam;
public class LicenseVertify {
/**
* 公钥别名
*/
private String pubAlias;
/**
* 该密码是在使用keytool生成密钥对时设置的密钥库的访问密码
*/
private String keyStorePwd;
/**
* 系统的统一识别码
*/
private String onlykey;
/**
* 证书路径
*/
private String licName;
/**
* 公钥库路径
*/
private String pubPath;
private String confPath="licenseVertifyConf.properties";
public LicenseVertify(String onlykey){
setConf(confPath,onlykey);
}
public LicenseVertify(String confPath,String onlykey){
setConf(confPath,onlykey);
}
public void setConf(String confPath,String onlykey){
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream(confPath);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
this.onlykey = onlykey;
pubAlias = prop.getProperty("public.alias");
keyStorePwd = prop.getProperty("key.store.pwd");
licName = prop.getProperty("license.name");
pubPath = prop.getProperty("public.store.path");
}
private LicenseParam initLicenseParams(){
Class<LicenseVertify> clazz = LicenseVertify.class;
Preferences pre = Preferences.userNodeForPackage(clazz);
CipherParam cipherParam = new DefaultCipherParam(keyStorePwd);
KeyStoreParam pubStoreParam = new DefaultKeyStoreParam(
clazz,pubPath,pubAlias,keyStorePwd,null);
LicenseParam licenseParam = new DefaultLicenseParam(
onlykey,pre,pubStoreParam,cipherParam);
return licenseParam;
}
private LicenseManager getLicenseManager(){
return LicenseManagerHolder.getLicenseManager(initLicenseParams());
}
public void install(String licdir){
try {
LicenseManager licenseManager = getLicenseManager();
//path=D:\eclipse_mars_workspace\LicenseTest\license.lic
System.out.println("path="+(licdir+File.separator+licName));
File file = new File(licdir+File.separator+licName);
licenseManager.install(file);
System.out.println("安装证书成功!");
} catch (Exception e) {
System.out.println("安装证书失败!");
e.printStackTrace();
System.exit(0);
}
}
public int vertify(){
try {
LicenseManager licenseManager=getLicenseManager();
licenseManager.verify();
System.out.println("验证证书成功!");
return 0;
} catch(LicenseContentException ex){
System.out.println("证书已过期");
ex.printStackTrace();
return 1;
}catch (Exception e) {
System.out.println("验证证书失败!");
e.printStackTrace();
return 2;
}
}
}
参数配置文件:licenseVertifyConf.properties
##########common parameters###########
#公钥别名
public.alias=myPublicCert01
#公钥库密码(与密钥库密码一致)
key.store.pwd=wq@123
#第二步中生成的license文件的名字,代码中会拼上类路径
license.name=license.lic
#公钥库文件位置,相对路径,类路径下
public.store.path=/myPublicCerts01.store
测试代码:
package com.iss.license.verify;
public class Test {
public static void main(String[] args) throws Exception
{
LicenseVertify vlicense=new LicenseVertify("happy"); // 项目唯一识别码,对应生成配置文件的subject
vlicense.install(System.getProperty("user.dir")); //D:\eclipse_mars_workspace\LicenseTest
vlicense.vertify();
}
}
完成!