javaEE防盗版-License开发
生活随笔
收集整理的這篇文章主要介紹了
javaEE防盗版-License开发
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
前言
開(kāi)發(fā)的軟件產(chǎn)品在交付使用的時(shí)候,往往會(huì)授權(quán)一段時(shí)間的試用期,這個(gè)時(shí)候license就派上用場(chǎng)了。不同于在代碼中直接加上時(shí)間約束,需要重新授權(quán)的時(shí)候使用license可以避免修改源碼,改動(dòng)部署,授權(quán)方直接生成一個(gè)新的license發(fā)送給使用方替換掉原來(lái)的license文件即可。下面將講述使用truelicense來(lái)實(shí)現(xiàn)license的生成和使用。Truelicense是一個(gè)開(kāi)源的證書(shū)管理引擎,詳細(xì)介紹見(jiàn)https://truelicense.java.net/ license于加密技術(shù)一起使用效果更好。 接下來(lái)介紹一下license授權(quán)機(jī)制的原理:1、生成密鑰對(duì),方法有很多。
2、授權(quán)者保留私鑰,使用私鑰對(duì)包含授權(quán)信息(如使用截止日期,MAC地址等)的license進(jìn)行數(shù)字簽名。
3、公鑰給使用者(放在驗(yàn)證的代碼中使用),用于驗(yàn)證license是否符合使用條件。
使用方式
1. 生成密鑰對(duì)
以下命令在dos命令行執(zhí)行,注意當(dāng)前執(zhí)行目錄,最后生成的密鑰對(duì)即在該目錄下:1、首先要用KeyTool工具來(lái)生成私匙庫(kù):(-alias別名 –validity 3650表示10年有效)
keytool -genkey -alias privatekey -keystore privateKeys.store -validity 3650
?
這里口令使用了noryar123
?
這里的口令是:noryar456
這個(gè)時(shí)候,會(huì)在打開(kāi)命令行的地方創(chuàng)建出一個(gè)文件,privateKeys.store
2、然后把私匙庫(kù)內(nèi)的證書(shū)導(dǎo)出到一個(gè)文件當(dāng)中:
keytool -export -alias privatekey -file certfile.cer -keystore privateKeys.store
?
口令:noryar123
3、然后再把這個(gè)證書(shū)文件導(dǎo)入到公匙庫(kù):
keytool -import -alias publiccert -file certfile.cer -keystore publicCerts.store
?
這里的口令,用了:noryar123
最后生成文件privateKeys.store、publicCerts.store拷貝出來(lái)備用。
文件位置在用戶目錄下
C:\Users\Administrator
從上面我們可以看到,密鑰一共有兩種:1. 密鑰庫(kù),這個(gè)需要配置到服務(wù)器中。2. 密鑰,這個(gè)需要保護(hù)好,是創(chuàng)建私鑰的時(shí)候用的
2. Maven
<!-- 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>3. 生成證書(shū) (該部分代碼由授權(quán)者獨(dú)立保管執(zhí)行)
package com.noryar.license; import de.schlichtherle.license.LicenseManager; import de.schlichtherle.license.LicenseParam; /*** 單例模式下的證書(shū)管理器* @author Leon Lee.*/ 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;} }package com.noryar.license;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;/*** 生成證書(shū)* @author Leon Lee.*/ 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 ;/*** 該密碼生成密鑰對(duì)的密碼*/private String privateKeyPwd ;/*** 使用keytool生成密鑰對(duì)時(shí)設(shè)置的密鑰庫(kù)的訪問(wèn)密碼*/private String keyStorePwd ;private String subject ;private String priPath ;// X500Princal是一個(gè)證書(shū)文件的固有格式,詳見(jiàn)APIprivate final static X500Principal DEFAULTHOLDERANDISSUER = new X500Principal("CN=noryar, OU=noryar, O=noryar, L=china, ST=dalian, C=china");public LicenseMake(){}public LicenseMake(String confPath){initParam(confPath);}/*** 讀取屬性文件* @param propertiesPath 屬性文件路徑*/public void initParam(String confPath) {// 獲取參數(shù)Properties prop = new Properties();InputStream in = getClass().getResourceAsStream(confPath);try{prop.load(in);}catch (IOException e){e.printStackTrace();}//common parampriAlias = 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 contentissued = 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");}/*** 初始化證書(shū)的相關(guān)參數(shù)* @return*/private LicenseParam initLicenseParams(){Class<LicenseMake> clazz=LicenseMake.class;Preferences pre = Preferences.userNodeForPackage(clazz);// 設(shè)置對(duì)證書(shū)內(nèi)容加密的對(duì)稱(chēng)密碼CipherParam cipherParam = new DefaultCipherParam(keyStorePwd);// 參數(shù)1,2從哪個(gè)Class.getResource()獲得密鑰庫(kù);//參數(shù)3密鑰庫(kù)的別名;//參數(shù)4密鑰庫(kù)存儲(chǔ)密碼;//參數(shù)5密鑰庫(kù)密碼KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(clazz, priPath, priAlias, keyStorePwd, privateKeyPwd);// 返回生成證書(shū)時(shí)需要的參數(shù)LicenseParam licenseParam = new DefaultLicenseParam(subject,pre, privateStoreParam, cipherParam);return licenseParam;}/*** 通過(guò)外部配置文件構(gòu)建證書(shū)的的相關(guān)信息* @return* @throws ParseException*/public LicenseContent buildLicenseContent() throws ParseException{LicenseContent content=new LicenseContent();SimpleDateFormat formate=new SimpleDateFormat("yyyy-MM-dd");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;}/*** 生成證書(shū),在證書(shū)發(fā)布者端執(zhí)行* @throws Exception */public void create() throws Exception{LicenseManager licenseManager=LicenseManagerHolder.getLicenseManager(initLicenseParams());LicenseContent content=buildLicenseContent();licenseManager.store(content, new File(licPath));System.out.println("證書(shū)發(fā)布成功");} }
licenseMakeConf.properties ##########common parameters########### #私鑰的別名 private.key.alias=privatekey #privateKeyPwd(該密碼生成密鑰對(duì)的密碼,需要妥善保管,不能讓使用者知道) private.key.pwd=noryar456 #keyStorePwd(該密碼是在使用keytool生成密鑰對(duì)時(shí)設(shè)置的密鑰庫(kù)的訪問(wèn)密碼) key.store.pwd=noryar123 #項(xiàng)目的唯一識(shí)別碼 subject=noryar #生成證書(shū)的地址 licPath=license.lic #密鑰庫(kù)的地址 priPath=privateKeys.store ##########license content########### #發(fā)布日期 issuedTime=2016-07-25 #有效開(kāi)始日期 notBefore=2016-07-25 #有效截止日期 notAfter=2016-08-30 #consumerType consumerType=user #ConsumerAmount consumerAmount=1 #info info=this is a license
測(cè)試方法 public static void main(String[] args) throws Exception{LicenseMake clicense=new LicenseMake("/licenseMakeConf.properties");clicense.create();} 以上就可以創(chuàng)建出一個(gè)license文件了。然后開(kāi)發(fā)者將license文件傳遞給購(gòu)買(mǎi)方。購(gòu)買(mǎi)方在系統(tǒng)中上傳該文件進(jìn)行驗(yàn)證即可。
4. 驗(yàn)證證書(shū)
package com.noryar.license;import de.schlichtherle.license.LicenseManager; import de.schlichtherle.license.LicenseParam; /*** 單例模式下的證書(shū)管理器* @author Leon Lee*/ 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;} }認(rèn)證核心方法 package com.noryar.license;import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.prefs.Preferences;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生成密鑰對(duì)時(shí)設(shè)置的密鑰庫(kù)的訪問(wèn)密碼 */private String keyStorePwd;/*** 系統(tǒng)的統(tǒng)一識(shí)別碼*/private String onlykey;/*** 證書(shū)路徑 */private String licName;/*** 公鑰庫(kù)路徑*/private String pubPath;private String confPath="/licenseVertifyConf.properties";public LicenseVertify(String onlykey){setConf(confPath,onlykey);}public LicenseVertify(String confPath,String onlykey){setConf(confPath,onlykey);}/*** 通過(guò)外部配置文件獲取配置信息* @param confPath 配置文件路徑* @param onlykey 系統(tǒng)的統(tǒng)一識(shí)別碼*/public void setConf(String confPath,String onlykey){// 獲取參數(shù)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");}/*** 初始化證書(shū)的相關(guān)參數(shù)* @param 系統(tǒng)的統(tǒng)一識(shí)別碼* @return*/private LicenseParam initLicenseParams(){Class<LicenseVertify> clazz=LicenseVertify.class;Preferences pre=Preferences.userNodeForPackage(clazz);CipherParam cipherParam=new DefaultCipherParam(storePwd);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());}/*** 安裝證書(shū)證書(shū)* @param 存放證書(shū)的路徑* @return*/public void install(String licdir){try{LicenseManager licenseManager=getLicenseManager();licenseManager.install(new File(licdir+File.separator+licName));System.out.println("安裝證書(shū)成功!");}catch (Exception e){System.out.println("安裝證書(shū)失敗!");e.printStackTrace();System.exit(0);}}/*** 驗(yàn)證證書(shū)的合法性* @return 0、合法,1、證書(shū)過(guò)期,2、證書(shū)錯(cuò)誤*/public int vertify(){try{LicenseManager licenseManager=getLicenseManager();licenseManager.verify();System.out.println("驗(yàn)證證書(shū)成功!");return 0;}catch(LicenseContentException ex){System.out.println("證書(shū)已經(jīng)過(guò)期!");ex.printStackTrace();return 1;}catch (Exception e){System.out.println("驗(yàn)證證書(shū)失敗!");e.printStackTrace();return 2;}} }
測(cè)試 public static void main(String[] args) throws Exception{LicenseVertify vlicense=new LicenseVertify("noryar"); // 項(xiàng)目唯一識(shí)別碼,對(duì)應(yīng)生成配置文件的subjectvlicense.install(System.getProperty("user.dir"));vlicense.vertify();} licenseVertifyConf.properties ##########common parameters########### #公鑰別名 public.alias=publiccert #使用keytool生成密鑰對(duì)時(shí)設(shè)置的密鑰庫(kù)的訪問(wèn)密碼 key.store.pwd= noryar123 #證書(shū)路徑 license.name=license.lic #公共庫(kù)路徑 public.store.path=publicCerts.store
總結(jié)
以上就是license開(kāi)發(fā)的常規(guī)手段。對(duì)于web項(xiàng)目來(lái)說(shuō),只需要提供license認(rèn)證模塊的開(kāi)發(fā)即可。對(duì)于開(kāi)發(fā)者來(lái)說(shuō),可以將license生成單獨(dú)開(kāi)發(fā)一個(gè)小程序。以后就可以通過(guò)這個(gè)程序來(lái)給不同的企業(yè)生成license。此外,為了更好的保護(hù)代碼。license認(rèn)證模塊可以進(jìn)行混淆加密,解密部分使用C語(yǔ)言來(lái)編寫(xiě),同時(shí)針對(duì)不同的平臺(tái)進(jìn)行編譯。增強(qiáng)破解難度。
總結(jié)
以上是生活随笔為你收集整理的javaEE防盗版-License开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java里重写toString的作用
- 下一篇: 虚幻浏览器插件 加载透明网页