truelicense 添加mac验证说明及demo下载

truelicense相关原理可以参考第一篇:http://blog.csdn.net/luckymelina/article/details/22870665
本文参考第二篇:http://blog.csdn.net/jingshuaizh/article/details/44461289

第一篇能够让刚接触truelicense的童鞋很成功的上手并测试成功,由于项目需要mac验证,所以参考第二篇,介于发现有些网友反应有错误,本人也遇到错误,后贴上成功运行的工程仅供参考。

添加mac验证功能需要修改truelicense源码,可以参考第二篇的git地址下载源码:https://github.com/jingshauizh/JavaSpringSurmmary/tree/master/java-license-jar

添加mac验证的原理是添加mac信息到license context 并生成license文件,然后在验证程序中加入mac验证算法,验证时读取license文件中的mac信息,然后验证~


接下来是本例制作license的具体步骤:

使用keytool生成密钥对

以下命令在dos命令行执行,注意当前执行目录,最后生成的密钥对即在该目录下:

1、首先要用KeyTool工具来生成私匙库:(-alias别名 –validity 3650表示10年有效)

keytool -genkey -alias privatekey -keystore privateKeys.store -validity 3650

2、然后把私匙库内的公匙导出到一个文件当中:

keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store

3、然后再把这个证书文件导入到公匙库:

keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store

最后生成文件privateKeys.store、publicCerts.store拷贝出来备用。

以上是在windows机器上的预备动作。

接下来开始修改程序

1、修改生成licence代码。

生成license程序中 createparam.properties:

##########common parameters###########
#alias
PRIVATEALIAS=privatekey
#key(该密码生成密钥对的密码,需要妥善保管,不能让使用者知道) 
KEYPWD=bigdata123456
#STOREPWD(该密码是在使用keytool生成密钥对时设置的密钥库的访问密码)
STOREPWD=abc123456
#SUBJECT
SUBJECT=bigdata
#licPath
licPath=bigdata.lic
#priPath
priPath=privateKeys.store
##########license content###########
#issuedTime
issuedTime=2017-05-01
#notBeforeTime
notBefore=2017-05-01
#notAfterTime
notAfter=2017-06-10
#consumerType
consumerType=user
#ConsumerAmount
consumerAmount=1
#info
info=this is a license
#mac
mac=D8-CB-8A-04-51-10

然后通过content.setExtra()方法添加mac信息到license content,这是主要生成license的代码CreateLicense.java:

//license content
        issuedTime = 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");
        mac = prop.getProperty("mac");
        ip = prop.getProperty("ip");
            content.setConsumerType(consumerType);
            content.setConsumerAmount(consumerAmount);
            content.setInfo(info);

            // 扩展
            //content.setExtra(new Object());
            content.setExtra(mac);

这里的setExtra可以传入一个object,如果除了mac地址还需要其他验证,可以传入一个model类,这里只传入一个mac String字符串。
以上修改即可完成licence文件生成。

2、修改验证licence代码

验证时使用到的Properties文件如下:

##########common parameters###########
#alias
PUBLICALIAS=publiccert
#STOREPWD
STOREPWD=abc123456
#SUBJECT
SUBJECT=bigdata
#licPath
licPath=D:\\tmp\\bigdata.lic
#pubPath
pubPath=D:\\tmp\\publicCerts.store

接下来修改LicenseManager.java源码中的validate方法,主要是从licence中读取mac值并使用算法进行验证。

String macAddress = paramLicenseContent.getExtra().toString();

        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);
        }

ListNets类如下:


package zlicense.de.schlichtherle.utils;


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 = "192.168.3.212";
        String mac = "D8-CB-8A-04-51-10";
        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;

    }
}

这里只用到了其中一个验证mac的算法,如果有其他需求,可以在这里添加验证。
最后是生成和验证程序的入口(不需要修改,只执行):

public class licenseCreateTest {
    public static void main(String[] args){
        CreateLicense cLicense = new CreateLicense();
        //获取参数
        cLicense.setParam("./param.properties");
        //生成证书
        cLicense.create();
    }
}
public class licenseVerifyTest {
    public static void main(String[] args){
        VerifyLicense vLicense = new VerifyLicense();
        //获取参数
        vLicense.setParam("D:\\tmp\\param.properties");
        //生成证书
        vLicense.verify();
    }
}

到这里代码修改完毕。有一个需要注意的问题:生成和验证licence的工程包名需要一致,否则会报强转错误。

以上逻辑搞清楚后,完全可以自己测试了。这里放上我的测试工程,仅供参考:
http://download.csdn.net/download/qq_27499099/9838931

猜你喜欢

转载自blog.csdn.net/qq_27499099/article/details/71566000