由于公司开发的软件需要拿到交警内网使用,又不是真实版,没有采用加密狗而采用的是license的方式进行加密,当然这种加密方式并不安全,但是我们的系统在运行是有时间限制的,如果修改时间,系统出来的数据也是不准的,所以可以采用这种方式进行加密。
首先是创建密钥
keytool -genkey -alias privatekey -keystore privateKeys.store -validity 3650
然后把私匙库内的公匙导出到一个文件当中
keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store
然后再把这个证书文件导入到公匙库
keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store
最后生成文件privateKeys.store、publicCerts.store拷贝出来备用
然后是创建自己的生成license文件的方法
采用窗体程序进行生成密钥,我们要求的功能独立,有mac地址和功能分来,附带一些参数进行验证
传入对应的license文件生成地址 开始时间和结束时间,对应的加密内容
String licPathParam = this.licPath.getText()+"\\bayonet.lic";
CreateLicense createLicense = new CreateLicense();
createLicense.setParam("param.properties", method.toString(), txtStartParam, txtEndParam, licPathParam);
boolean flag = createLicense.create();
if(flag){
JOptionPane.showMessageDialog(this, "密钥生成成功", "提示",JOptionPane.INFORMATION_MESSAGE);
}else{
JOptionPane.showMessageDialog(this, "密钥生成失败", "提示",JOptionPane.ERROR_MESSAGE);
}
将加密内容写入对应的扩展属性中
public class CreateLicense {
//common param
private static String PRIVATEALIAS = "";
private static String KEYPWD = "";
private static String STOREPWD = "";
private static String SUBJECT = "";
private static String licPath = "";
private static String priPath = "";
private static String mac = "";
//license content
private static String issuedTime = "";
private static String notBefore = "";
private static String notAfter = "";
private static String consumerType = "";
private static int consumerAmount = 0;
private static String info = "";
// 为了方便直接用的API里的例子
// X500Princal是一个证书文件的固有格式,详见API
private final static X500Principal DEFAULTHOLDERANDISSUER = new X500Principal(
"CN=Duke、OU=JavaSoft、O=Sun Microsystems、C=US");
public void setParam(String propertiesPath,String macParam,String notBeforeParam,String notAfterParam,String licPathParam) {
// 获取参数
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream(propertiesPath);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
PRIVATEALIAS = prop.getProperty("PRIVATEALIAS");
KEYPWD = prop.getProperty("KEYPWD");
STOREPWD = prop.getProperty("STOREPWD");
SUBJECT = prop.getProperty("SUBJECT");
priPath = prop.getProperty("priPath");
//license content
issuedTime = prop.getProperty("issuedTime");
consumerType = prop.getProperty("consumerType");
consumerAmount = Integer.valueOf(prop.getProperty("consumerAmount"));
info = prop.getProperty("info");
mac = macParam;
licPath = licPathParam;
notBefore = notBeforeParam;
notAfter = notAfterParam;
}
public boolean create() {
try {
/************** 证书发布者端执行 ******************/
LicenseManager licenseManager = LicenseManagerHolder
.getLicenseManager(initLicenseParams0());
licenseManager.store((createLicenseContent()), new File(licPath));
} catch (Exception e) {
e.printStackTrace();
System.out.println("客户端证书生成失败!");
return false;
}
System.out.println("服务器端生成证书成功!");
return true;
}
// 返回生成证书时需要的参数
private static LicenseParam initLicenseParams0() {
Preferences preference = Preferences
.userNodeForPackage(CreateLicense.class);
// 设置对证书内容加密的对称密码
CipherParam cipherParam = new DefaultCipherParam(STOREPWD);
// 参数1,2从哪个Class.getResource()获得密钥库;参数3密钥库的别名;参数4密钥库存储密码;参数5密钥库密码
KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(
CreateLicense.class, priPath, PRIVATEALIAS, STOREPWD, KEYPWD);
LicenseParam licenseParams = new DefaultLicenseParam(SUBJECT,
preference, privateStoreParam, cipherParam);
return licenseParams;
}
// 从外部表单拿到证书的内容
public final static LicenseContent createLicenseContent() {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
LicenseContent content = null;
content = new LicenseContent();
content.setSubject(SUBJECT);
content.setHolder(DEFAULTHOLDERANDISSUER);
content.setIssuer(DEFAULTHOLDERANDISSUER);
try {
content.setIssued(format.parse(issuedTime));
content.setNotBefore(format.parse(notBefore));
content.setNotAfter(format.parse(notAfter));
} catch (ParseException e) {
e.printStackTrace();
}
content.setConsumerType(consumerType);
content.setConsumerAmount(consumerAmount);
content.setInfo(info);
// 扩展
content.setExtra(mac);
return content;
}
}
然后是对应的验证部分
public class MyLicenseManager extends LicenseManager { public MyLicenseManager(LicenseParam licenseParam) { super(licenseParam); } @Override protected synchronized void validate(LicenseContent var1) throws LicenseContentException { super.validate(var1); String extra = var1.getExtra().toString(); String[] paramList = extra.split(","); String mac = paramList[paramList.length-1]; if (!MacUtils.getMac().equals(mac)) { throw new LicenseContentException((new ObfuscatedString(new long[]{1000558500458715757L, -6998261911041258483L, -5490039629745846648L, 3561172928787106880L})).toString()); } if(SystemService.method.size()!=paramList.length-1){ for (int i=0;i<paramList.length-1;i++){ if(StringUtils.isNotBlank(paramList[i])){ SystemService.method.add(paramList[i]); } } } } }