標籤:
使用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 地址的配置
##########common parameters############aliasPRIVATEALIAS=privateKeys#key(important!)KEYPWD=iptv1234#STOREPWDSTOREPWD=iptv1234#SUBJECTSUBJECT=bigdata#licPathlicPath=C:/9exce/license/license.lic#priPathpriPath=C:/9exce/license/PrivateKeys.keystore##########license content############issuedTimeissuedTime=2015-03-09#notBeforeTimenotBefore=2015-03-09#notAfterTimenotAfter=2016-03-20#ip addressipAddress=150.236.220.200#mac addressmacAddress=80-00-0B-56-3B-32#consumerTypeconsumerType=user#ConsumerAmountconsumerAmount=1#infoinfo=this is a license
因為增加了mac地址,需要改變LicenseManager中的validate函數增加create_validate 用於create時的verify, 因為建立認證的時候 不能驗證mac地址。
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地址。
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 blockthrow 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地址的
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地址
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 中所有的檔案讀取方式,採用絕對路徑讀取。
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
使用truelicense進行Java程式license控制 經過擴張可以驗證license 開始結束日期,驗證綁定給定mac地址