日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

License文档

發布時間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 License文档 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

License學習文檔

一、簡介

License,即版權許可證,一般用于收費軟件給付費用戶提供的訪問許可證明。根據應用部署位置的不同,一般可以分為以下兩種情況討論:

  • 應用部署在開發者自己的云服務器上。這種情況下用戶通過賬號登錄的形式遠程訪問,因此只需要在賬號登錄的時候校驗目標賬號的有效期、訪問權限等信息即可。
  • 應用部署在客戶的內網環境。因為這種情況開發者無法控制客戶的網絡環境,也不能保證應用所在服務器可以訪問外網,因此通常的做法是使用服務器許可文件,在應用啟動的時候加載證書,然后在登錄或者其他關鍵操作的地方校驗證書的有效性。

License使用前提:

想要使用License,我們需要明確證書內部的內容,生成方式,存儲位置,加密方法,證書內容校驗等。
使用原理:
1、生成密鑰對,包含私鑰和公鑰。 2、授權者保留私鑰,使用私鑰對授權信息諸如使用截止日期,mac 地址等內容生成 license 簽名證書。 3、公鑰給使用者,放在代碼中使用,用于驗證 license 簽名證書是否符合使用條件。

二、環境配置

1.導入依賴
<dependency><groupId>de.schlichtherle.truelicense</groupId><artifactId>truelicense-core</artifactId><version>1.33</version><scope>provided</scope> </dependency>

本機端口號和MAC地址記錄

{"ipAddress":["192.168.0.102"], //IP地址"macAddress":["B4-0E-DE-D1-ED-9F"], //MAC地址"cpuSerial":"178BFBFF00A50F00", //CPU序列號"mainBoardSerial":"YX026BMC" //主板序列號 }

License證書模板內容如下:實體類LicenseCreatorParam

{"subject":"ccx-models","privateAlias":"privateKey","keyPass":"5T7Zz5Y0dJFcqTxvzkH5LDGJJSGMzQ","storePass":"3538cef8e7","licensePath":"C:/Users/zifangsky/Desktop/license.lic","privateKeysStorePath":"C:/Users/zifangsky/Desktop/privateKeys.keystore","issuedTime":"2018-04-26 14:48:12","expiryTime":"2018-12-31 00:00:00", "consumerType":"User","consumerAmount":1,"description":"這是證書描述信息","licenseCheckModel":{"ipAddress":["192.168.245.1","10.0.5.22"],"macAddress":["00-50-56-C0-00-01","50-7B-9D-F9-18-41"],"cpuSerial":"BFEBFBFF000406E3","mainBoardSerial":"L1HF65E00X9"} }

三、使用JDK自帶的 keytool 工具生成公私鑰證書庫

1.keytool簡介
Keytool 是一個Java 數據證書的管理工具 ,Keytool 將密鑰(key)和證書(certificates)存在一個稱為keystore的文件中 在keystore里,包含兩種數據: 密鑰實體(Key entity)——密鑰(secret key)又或者是私鑰和配對公鑰(采用非對稱加密) 可信任的證書實體(trusted certificate entries)——只包含公鑰
2.項目中的使用

以下命令在 window cmd 命令窗口執行,注意當前執行目錄,最后生成的密鑰對即在該目錄下:
1、首先要用 KeyTool 工具來生成私匙庫:(-alias別名 -validity 3650 表示10年有效)

#生成命令 keytool -genkey -alias privatekey -keysize 1024 -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(公鑰)拷貝出來備用。

密鑰需包含字母+數字 踩坑:The password does not match the default policy: At least six characters cons 密碼與默認策略不匹配:至少6個字符

上述命令執行完成之后,會在當前路徑下生成三個文件,分別是:privateKeys.keystore、publicCerts.keystore、certfile.cer。其中文件certfile.cer不再需要可以刪除,文件privateKeys.keystore用于當前的項目給客戶生成license文件,而文件publicCerts.keystore則隨應用代碼部署到客戶服務器,用戶解密license文件并校驗其許可信息。

注意:我們使用的公鑰和私鑰分別如下

privateKeys: private1234 publicCerts: public1234

四、為客戶生成license文件

1.建立一個單例模式下的證書管理器
public class LicenseManagerHolder {private static volatile LicenseManager licenseManager = null;private LicenseManagerHolder() {}public static LicenseManager getLicenseManager(LicenseParam param) {if (licenseManager == null) {synchronized (LicenseManagerHolder.class) {if (licenseManager == null) {licenseManager = new LicenseManager(param);}}}return licenseManager;} }
2.配置證書和公私鑰內容

在licenseMakeConf.properties配置文件中配置私鑰的配置信息和自定義的項目證書信息,該配置信息用于為客戶生成License證書文件,內容如下:

##########common parameters########### #私鑰的別名 private.key.alias=privatekey #privateKeyPwd(該密碼生成密鑰對的密碼,需要妥善保管,不能讓使用者知道) private.key.pwd=private1234 #keyStorePwd(該密碼是在使用keytool生成密鑰對時設置的密鑰庫的訪問密碼) key.store.pwd=public1234 #項目的唯一識別碼 subject=licenseTest #生成證書的地址 licPath=D:/license/license.lic #密鑰庫的地址 priPath=/privateKeys.store ##########license content########### #發布日期 issuedTime=2021-07-25 #有效開始日期 notBefore=2021-07-25 #有效截止日期 notAfter=2022-08-30 # ip 地址 ipAddress=192.168.0.102 # mac 地址 macAddress=B4-0E-DE-D1-ED-9F # 使用者類型,用戶(user)、電腦(computer)、其他(else) consumerType=user # 證書允許使用的消費者數量 consumerAmount=1 # 證書說明 info=power by xiamen yungu

在licenseVertifyConf.properties配置文件中配置證書驗證時所需的配置信息,內容如下:

##########common parameters########### #公鑰別名 public.alias=publiccert #使用keytool生成密鑰對時設置的密鑰庫的訪問密碼 key.store.pwd= public1234 #證書路徑 license.name=license.lic #公共庫路徑 public.store.path=/publicCerts.store #項目的唯一識別碼 subject=licenseTest
3.生成License文件
@Slf4j public class CreateLicense {/*** X500Princal 是一個證書文件的固有格式,詳見API*/private final static X500Principal DEFAULT_HOLDERAND_ISSUER = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");private String priAlias;private String privateKeyPwd;private String keyStorePwd;private String subject;private String priPath;private String issued;private String notBefore;private String notAfter;private String ipAddress;private String macAddress;private String consumerType;private int consumerAmount;private String info;private String licPath;/*** 構造器,參數初始化** @param confPath 參數配置文件路徑*/public CreateLicense(String confPath) {// 獲取參數Properties prop = new Properties();try (InputStream in = getClass().getResourceAsStream(confPath)) {prop.load(in);} catch (IOException e) {log.error("CreateLicense Properties load inputStream error.", e);}//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");// license contentissued = prop.getProperty("issuedTime");notBefore = prop.getProperty("notBefore");notAfter = prop.getProperty("notAfter");ipAddress = prop.getProperty("ipAddress");macAddress = prop.getProperty("macAddress");consumerType = prop.getProperty("consumerType");consumerAmount = Integer.valueOf(prop.getProperty("consumerAmount"));info = prop.getProperty("info");licPath = prop.getProperty("licPath");}/*** 生成證書,在證書發布者端執行** @throws Exception*/public void create() throws Exception {LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(initLicenseParams());licenseManager.store(buildLicenseContent(), new File(licPath));log.info("------ 證書發布成功 ------");}/*** 初始化證書的相關參數** @return*/private LicenseParam initLicenseParams() {Class<CreateLicense> clazz = CreateLicense.class;Preferences preferences = Preferences.userNodeForPackage(clazz);// 設置對證書內容加密的對稱密碼CipherParam cipherParam = new DefaultCipherParam(keyStorePwd);// 參數 1,2 從哪個Class.getResource()獲得密鑰庫;// 參數 3 密鑰庫的別名;// 參數 4 密鑰庫存儲密碼;// 參數 5 密鑰庫密碼KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(clazz, priPath, priAlias, keyStorePwd, privateKeyPwd);// 返回生成證書時需要的參數return new DefaultLicenseParam(subject, preferences, privateStoreParam, cipherParam);}/*** 通過外部配置文件構建證書的的相關信息** @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(DEFAULT_HOLDERAND_ISSUER);content.setIssuer(DEFAULT_HOLDERAND_ISSUER);content.setIssued(formate.parse(issued));content.setNotBefore(formate.parse(notBefore));content.setNotAfter(formate.parse(notAfter));content.setInfo(info);// 擴展字段Map<String, String> map = new HashMap<>(4);map.put("ip", ipAddress);map.put("mac", macAddress);content.setExtra(map);return content;} }
4.生成證書方法測試
public static void main(String[] args) throws Exception {CreateLicense clicense = new CreateLicense("/licenseCreateParam.properties");clicense.create(); }
5.測試結果
在配置文件對應的磁盤目錄中,系統可自動生成License許可證書,需注意,證書內部的開始時間,生效時間,結束時間要符合正常邏輯,否則無法生成License證書。

五、License校驗

1.書寫驗證License信息類

用公鑰驗證 license 證書,驗證用戶系統啟動時是否有證書且證書是否在生效期間內等信息。

package com.zony.metro.license;import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.prefs.Preferences;import de.schlichtherle.license.*; import lombok.extern.slf4j.Slf4j;@Slf4j public class LicenseVertify {/*** 公鑰別名*/private String pubAlias;/*** 該密碼是在使用keytool生成密鑰對時設置的密鑰庫的訪問密碼*/private String keyStorePwd;/*** 系統的統一識別碼*/private String onlykey;/*** 證書路徑*/private String licName;/*** 公鑰庫路徑*/private String pubPath;private String confPath="/licenseVertifyConf.properties";public LicenseVertify(String onlykey){setConf(confPath,onlykey);}public LicenseVertify(String confPath,String onlykey){setConf(confPath,onlykey);}/*** 通過外部配置文件獲取配置信息* @param confPath 配置文件路徑* @param onlykey 系統的統一識別碼*/public void setConf(String confPath,String onlykey){// 獲取參數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");keyStorePwd = prop.getProperty("key.store.pwd");}/*** 初始化證書的相關參數* @param //系統的統一識別碼* @return*/private LicenseParam initLicenseParams(){Class<LicenseVertify> clazz=LicenseVertify.class;Preferences pre=Preferences.userNodeForPackage(clazz);CipherParam cipherParam=new DefaultCipherParam(keyStorePwd);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());}/*** 安裝證書證書* @param //存放證書的路徑* @return*/public void install(String licdir){try{LicenseManager licenseManager=getLicenseManager();licenseManager.install(new File(licdir+File.separator+licName));System.out.println("安裝證書成功!");}catch (Exception e){System.out.println("安裝證書失敗!");e.printStackTrace();System.exit(0);}}/*** 驗證證書的合法性* @return 0、合法,1、證書過期,2、證書錯誤*/public int vertify(){try{LicenseManager licenseManager=getLicenseManager();licenseManager.verify();System.out.println("驗證證書成功!");return 0;}catch(LicenseContentException ex){System.out.println("證書已經過期!");ex.printStackTrace();return 1;}catch (Exception e){System.out.println("驗證證書失敗!");e.printStackTrace();return 2;}}/*** 驗證證書的合法性*/public boolean vertifyExtra() {try {LicenseManager licenseManager = getLicenseManager();LicenseContent verify = licenseManager.verify();log.info("驗證證書成功!");Map<String, String> extra = (Map) verify.getExtra();String ip = extra.get("ip");InetAddress inetAddress = InetAddress.getLocalHost();String localIp = inetAddress.toString().split("/")[1];if (!Objects.equals(ip, localIp)) {log.error("IP 地址驗證不通過");return false;}String mac = extra.get("mac");String localMac = getLocalMac(inetAddress);if (!Objects.equals(mac, localMac)) {log.error("MAC 地址驗證不通過");return false;}log.info("IP、MAC地址驗證通過");return true;} catch (LicenseContentException ex) {log.error("證書已經過期!", ex);return false;} catch (Exception e) {log.error("驗證證書失敗!", e);return false;}}/*** 得到本機 mac 地址** @param inetAddress* @throws //SocketException*/private String getLocalMac(InetAddress inetAddress) throws SocketException {//獲取網卡,獲取地址byte[] mac = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();StringBuffer sb = new StringBuffer();for (int i = 0; i < mac.length; i++) {if (i != 0) {sb.append("-");}//字節轉換為整數int temp = mac[i] & 0xff;String str = Integer.toHexString(temp);if (str.length() == 1) {sb.append("0" + str);} else {sb.append(str);}}return sb.toString().toUpperCase();} }
2.項目啟動時,安裝證書并驗證信息

在項目啟動時,加載并安裝License證書信息,然后進行License證書內容判斷,如果項目未安裝證書或證書內容不合法,則項目無法啟動。

@Component public class LicenseCheck {@PostConstructpublic void init() {VerifyLicense vlicense = new VerifyLicense();vlicense.install();if (!vlicense.vertify()) {Runtime.getRuntime().halt(1);}} }
3.添加用戶類型,用戶數量驗證
/*** 驗證證書的合法性*/ public boolean vertifyExtra(Map<String,Object> userLicenseContent) {try {LicenseManager licenseManager = getLicenseManager();//證書內部信息LicenseContent verify = licenseManager.verify();log.info("驗證證書成功!");Map<String, String> extra = (Map) verify.getExtra();String ip = extra.get("ip");InetAddress inetAddress = InetAddress.getLocalHost();String localIp = inetAddress.toString().split("/")[1];if (!Objects.equals(ip, localIp)) {log.error("IP 地址驗證不通過");return false;}String mac = extra.get("mac");String localMac = getLocalMac(inetAddress);if (!Objects.equals(mac, localMac)) {log.error("MAC 地址驗證不通過");return false;}log.info("IP、MAC地址驗證通過");//授權用戶數量驗證int consumerAmount = verify.getConsumerAmount();Integer userConsumerAmount = (Integer)userLicenseContent.get("userConsumerAmount");if(userConsumerAmount > consumerAmount){log.error("用戶數量過大");return false;}//授權對象驗證String consumerType = verify.getConsumerType();String userConsumerType = (String)userLicenseContent.get("userConsumerType");if(!consumerType.equals(userConsumerType)){log.error("該用戶并不是授權用戶");return false;}return true;} catch (LicenseContentException ex) {log.error("證書已經過期!", ex);return false;} catch (Exception e) {log.error("驗證證書失敗!", e);return false;} }

在測試時,需要獲取到用戶的數量以及用戶的類型,這里直接賦值了。

/***@Description 安裝證書,并驗證證書的合法性*@Param []*@Return void*@Author ChuXu*@Date 2021/9/23*@Time 17:06*/ @Test public void testInstallLicense(){LicenseVertify vlicense=new LicenseVertify("licenseTest"); // 項目唯一識別碼,對應生成配置文件的subject// vlicense.install(System.getProperty("D:/license"));vlicense.install("D:/license");//驗證License證書的基本信息// vlicense.vertify();//驗證License證書內部IP,MAC地址,用戶數量,用戶類型等信息Map<String, Object> map = new HashMap<>();map.put("userConsumerAmount",1);map.put("userConsumerType","op");vlicense.vertifyExtra(map); }

參考文檔:
https://www.cnblogs.com/jmcui/p/11909579.html
https://www.zifangsky.cn/1277.html

總結

以上是生活随笔為你收集整理的License文档的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。