使用truelicense进行Java程序license控制
经过扩张可以验证license 开始结束日期,验证绑定给定mac地址。
Truelicense 是一个开源的Java license 验证项目。
使用truelicense实现用于JAVA工程license机制(包括license生成和验证)请参考http://www.it165.net/pro/html/201404/11540.html
其中包括license授权机制的原理和制作license的具体步骤
本文主要是在此文基础上增加了mac 地址验证:
在createparam.properties
中增加 ip地址和 mac 地址的配置
[html] view plain copy
- ##########common parameters###########
- #alias
- PRIVATEALIAS=privateKeys
- #key(important!)
- KEYPWD=iptv1234
- #STOREPWD
- STOREPWD=iptv1234
- #SUBJECT
- SUBJECT=bigdata
- #licPath
- licPath=C:/9exce/license/license.lic
- #priPath
- priPath=C:/9exce/license/PrivateKeys.keystore
- ##########license content###########
- #issuedTime
- issuedTime=2015-03-09
- #notBeforeTime
- notBefore=2015-03-09
- #notAfterTime
- notAfter=2016-03-20
- #ip address
- ipAddress=150.236.220.200
- #mac address
- macAddress=80-00-0B-56-3B-32
- #consumerType
- consumerType=user
- #ConsumerAmount
- consumerAmount=1
- #info
- info=this is a license
因为增加了mac地址,需要改变LicenseManager中的validate函数增加create_validate 用于create时的verify, 因为创建证书的时候 不能验证mac地址。
[java] view plain copy
- protected synchronized void create_validate(LicenseContent paramLicenseContent)
- throws LicenseContentException {
- LicenseParam localLicenseParam = getLicenseParam();
- if (!localLicenseParam.getSubject().equals(
- paramLicenseContent.getSubject())) {
- throw new LicenseContentException(EXC_INVALID_SUBJECT);
- }
- if (paramLicenseContent.getHolder() == null) {
- throw new LicenseContentException(EXC_HOLDER_IS_NULL);
- }
- if (paramLicenseContent.getIssuer() == null) {
- throw new LicenseContentException(EXC_ISSUER_IS_NULL);
- }
- if (paramLicenseContent.getIssued() == null) {
- throw new LicenseContentException(EXC_ISSUED_IS_NULL);
- }
- Date localDate1 = new Date();
- Date localDate2 = paramLicenseContent.getNotBefore();
- if ((localDate2 != null) && (localDate1.before(localDate2))) {
- throw new LicenseContentException(EXC_LICENSE_IS_NOT_YET_VALID);
- }
- Date localDate3 = paramLicenseContent.getNotAfter();
- if ((localDate3 != null) && (localDate1.after(localDate3))) {
- throw new LicenseContentException(EXC_LICENSE_HAS_EXPIRED);
- }
- String str = paramLicenseContent.getConsumerType();
- if (str == null) {
- throw new LicenseContentException(EXC_CONSUMER_TYPE_IS_NULL);
- }
- Preferences localPreferences = localLicenseParam.getPreferences();
- if ((localPreferences != null) && (localPreferences.isUserNode())) {
- if (!USER.equalsIgnoreCase(str)) {
- throw new LicenseContentException(EXC_CONSUMER_TYPE_IS_NOT_USER);
- }
- if (paramLicenseContent.getConsumerAmount() != 1) {
- throw new LicenseContentException(
- EXC_CONSUMER_AMOUNT_IS_NOT_ONE);
- }
- } else if (paramLicenseContent.getConsumerAmount() <= 0) {
- throw new LicenseContentException(
- EXC_CONSUMER_AMOUNT_IS_NOT_POSITIVE);
- }
- }
更新validate增加验证客户server的mac地址。
[java] view plain copy
- protected synchronized void validate(LicenseContent paramLicenseContent)
- throws LicenseContentException {
- LicenseParam localLicenseParam = getLicenseParam();
- if (!localLicenseParam.getSubject().equals(
- paramLicenseContent.getSubject())) {
- throw new LicenseContentException(EXC_INVALID_SUBJECT);
- }
- if (paramLicenseContent.getHolder() == null) {
- throw new LicenseContentException(EXC_HOLDER_IS_NULL);
- }
- if (paramLicenseContent.getIssuer() == null) {
- throw new LicenseContentException(EXC_ISSUER_IS_NULL);
- }
- if (paramLicenseContent.getIssued() == null) {
- throw new LicenseContentException(EXC_ISSUED_IS_NULL);
- }
- Date localDate1 = new Date();
- Date localDate2 = paramLicenseContent.getNotBefore();
- if ((localDate2 != null) && (localDate1.before(localDate2))) {
- throw new LicenseContentException(EXC_LICENSE_IS_NOT_YET_VALID);
- }
- Date localDate3 = paramLicenseContent.getNotAfter();
- if ((localDate3 != null) && (localDate1.after(localDate3))) {
- throw new LicenseContentException(EXC_LICENSE_HAS_EXPIRED);
- }
- LicenseCheckModel licenseCheckModel = (LicenseCheckModel)paramLicenseContent.getExtra();
- String macAddress = licenseCheckModel.getIpMacAddress();
- try {
- if (!ListNets.validateMacAddress(macAddress)) {
- throw new LicenseContentException(EXC_LICENSE_HAS_EXPIRED);
- }
- } catch (SocketException e) {
- // TODO Auto-generated catch block
- throw new LicenseContentException(EXC_LICENSE_HAS_EXPIRED);
- }
- String str = paramLicenseContent.getConsumerType();
- if (str == null) {
- throw new LicenseContentException(EXC_CONSUMER_TYPE_IS_NULL);
- }
- Preferences localPreferences = localLicenseParam.getPreferences();
- if ((localPreferences != null) && (localPreferences.isUserNode())) {
- if (!USER.equalsIgnoreCase(str)) {
- throw new LicenseContentException(EXC_CONSUMER_TYPE_IS_NOT_USER);
- }
- if (paramLicenseContent.getConsumerAmount() != 1) {
- throw new LicenseContentException(
- EXC_CONSUMER_AMOUNT_IS_NOT_ONE);
- }
- } else if (paramLicenseContent.getConsumerAmount() <= 0) {
- throw new LicenseContentException(
- EXC_CONSUMER_AMOUNT_IS_NOT_POSITIVE);
- }
- }
创建类ListNets 用于读取客户server的IP地址和mac地址进行验证,笔者使用了验证mac地址的函数,毕竟客户有可能更改机器的ip地址的
[java] view plain copy
- package zlicense.util;
- import java.net.*;
- import java.util.*;
- import static java.lang.System.out;
- public class ListNets {
- public static void main(String args[]) throws SocketException {
- String ip = "150.236.220.200";
- String mac = "80-00-0B-56-3B-32";
- boolean flag = validatoIpAndMacAddress(ip, mac);
- boolean macflag = validateMacAddress( mac);
- out.printf("validatoMacAddress flag=%s\n", macflag);
- out.printf("validatoIpAndMacAddress flag=%s\n", flag);
- }
- static void displayInterfaceInformation(NetworkInterface netint)
- throws SocketException {
- out.printf("Display name: %s\n", netint.getDisplayName());
- out.printf("Name: %s\n", netint.getName());
- byte[] mac = netint.getHardwareAddress();
- if (mac != null) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < mac.length; i++) {
- sb.append(String.format("%02X%s", mac[i],
- (i < mac.length - 1) ? "-" : ""));
- }
- System.out.println("mac=" + sb.toString());
- }
- Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
- for (InetAddress inetAddress : Collections.list(inetAddresses)) {
- out.printf("InetAddress: %s\n", inetAddress);
- System.out
- .println("InetAddress ip=" + inetAddress.getHostAddress());
- }
- out.printf("\n");
- }
- public static boolean validateMacAddress(String macAddress)
- throws SocketException {
- boolean returnFlag = false;
- Enumeration<NetworkInterface> nets = NetworkInterface
- .getNetworkInterfaces();
- for (NetworkInterface netint : Collections.list(nets)) {
- byte[] mac = netint.getHardwareAddress();
- StringBuilder sb = new StringBuilder();
- if (mac != null) {
- for (int i = 0; i < mac.length; i++) {
- sb.append(String.format("%02X%s", mac[i],
- (i < mac.length - 1) ? "-" : ""));
- }
- System.out.println("mac=" + sb.toString());
- }
- if (sb.toString().equals(macAddress)) {
- returnFlag = true;
- }
- }
- return returnFlag;
- }
- public static boolean validatoIpAndMacAddress(String ipAddress,
- String macAddress) throws SocketException {
- boolean returnFlag = false;
- Enumeration<NetworkInterface> nets = NetworkInterface
- .getNetworkInterfaces();
- for (NetworkInterface netint : Collections.list(nets)) {
- byte[] mac = netint.getHardwareAddress();
- StringBuilder sb = new StringBuilder();
- if (mac != null) {
- for (int i = 0; i < mac.length; i++) {
- sb.append(String.format("%02X%s", mac[i],
- (i < mac.length - 1) ? "-" : ""));
- }
- System.out.println("mac=" + sb.toString());
- }
- if (sb.toString().equals(macAddress)) {
- Enumeration<InetAddress> inetAddresses = netint
- .getInetAddresses();
- String ip = "";
- for (InetAddress inetAddress : Collections.list(inetAddresses)) {
- ip = inetAddress.getHostAddress();
- System.out.println("InetAddress ip="
- + inetAddress.getHostAddress());
- if (ipAddress.toString().equals(ip)) {
- returnFlag = true;
- }
- }
- }
- }
- return returnFlag;
- }
- }
创建LicenseCheckModel 是一个model类就是存储 ip和mac地址
[java] view plain copy
- package zlicense.util;
- public class LicenseCheckModel {
- private String ipAddress;
- private String ipMacAddress;
- private String CPUSerial;
- private String motherboardSN;
- private String hardDiskSN;
- public String getIpAddress() {
- return ipAddress;
- }
- public void setIpAddress(String ipAddress) {
- this.ipAddress = ipAddress;
- }
- public String getIpMacAddress() {
- return ipMacAddress;
- }
- public void setIpMacAddress(String ipMacAddress) {
- this.ipMacAddress = ipMacAddress;
- }
- public String getCPUSerial() {
- return CPUSerial;
- }
- public void setCPUSerial(String cPUSerial) {
- CPUSerial = cPUSerial;
- }
- public String getMotherboardSN() {
- return motherboardSN;
- }
- public void setMotherboardSN(String motherboardSN) {
- this.motherboardSN = motherboardSN;
- }
- public String getHardDiskSN() {
- return hardDiskSN;
- }
- public void setHardDiskSN(String hardDiskSN) {
- this.hardDiskSN = hardDiskSN;
- }
- }
更新CreateLicense 增加mac和ip 的配置读取并写入license证书,采用了content.setExtra(licenseCheckModel);
将需要验证的信息 写入licenseCheckModel 然后set到content中。
改变了 truelicense 中所有的文件读取方式,采用绝对路径读取。
[java] view plain copy
- Properties prop= new Properties();
- //InputStream in= getClass().getResourceAsStream(propertiesPath);
- try {
- InputStreamin = new FileInputStream(propertiesPath);
- prop.load(in);
- } catch(IOException e) {
- // TODOAuto-generated catch block
- e.printStackTrace();
- }
所有的配置文件和我生成的 key stroe 在java-license-jar/src/main/resources文件夹下
项目code地址:
https://github.com/jingshauizh/JavaSpringSurmmary/tree/master/java-license-jar