欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot如何實(shí)現(xiàn)Web系統(tǒng)License授權(quán)認(rèn)證

 更新時間:2020年05月28日 11:58:30   作者:code2roc  
這篇文章主要介紹了Springboot如何實(shí)現(xiàn)Web系統(tǒng)License授權(quán)認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

在我們做系統(tǒng)級框架的時候,我們要一定程度上考慮系統(tǒng)的使用版權(quán),不能隨便一個人拿去在任何環(huán)境都能用,所以我們需要給我們系統(tǒng)做一個授權(quán)認(rèn)證機(jī)制,只有上傳了我們下發(fā)的lic文件并驗證通過,才能正常使用,下面就開始一步一步實(shí)現(xiàn)這個功能

1.生成機(jī)器碼

我們首先要做的就是對軟件部署的環(huán)境的唯一性進(jìn)行限制,這里使用的是macadderss,當(dāng)然你也可以換成cpu序列編號,并無太大影響,先上代碼

private static String getMac() {
    try {
      Enumeration<NetworkInterface> el = NetworkInterface
          .getNetworkInterfaces();
      while (el.hasMoreElements()) {
        byte[] mac = el.nextElement().getHardwareAddress();
        if (mac == null)
          continue;
        String hexstr = bytesToHexString(mac);
        return getSplitString(hexstr, "-", 2).toUpperCase();
      }
    } catch (Exception exception) {
      exception.printStackTrace();
    }
    return null;
  } 
 
public static String getMachineCode() throws Exception{
    Set<String> result = new HashSet<>();
    String mac = getMac();
    result.add(mac);
    Properties props = System.getProperties();
    String javaVersion = props.getProperty("java.version");
    result.add(javaVersion);
    String javaVMVersion = props.getProperty("java.vm.version");
    result.add(javaVMVersion);
    String osVersion = props.getProperty("os.version");
    result.add(osVersion);
    String code = Encrpt.GetMD5Code(result.toString());
    return getSplitString(code, "-", 4);
 
  }

這里進(jìn)行的操作是取出機(jī)器碼,與java版本,jvm,操作系統(tǒng)參數(shù)進(jìn)行混合,并進(jìn)行MD5操作

2.進(jìn)行l(wèi)ic文件的生成

這是我生成證書與進(jìn)行授權(quán)證書的界面,可以看到授權(quán)證書主要包含三個要素,機(jī)器碼,是否永久有效標(biāo)識,證書時效,我們會將這些數(shù)據(jù)寫入文本中并進(jìn)行加密處理,看下生成證書的代碼

public static void getLicense(String isNoTimeLimit, String licenseLimit, String machineCode, String licensePath, String priavateKeyPath) throws Exception{
    String[] liccontent = {
        "LICENSEID=yanpeng19940119@gmail.com",
        "LICENSENAME=YBLOG使用證書",
        MessageFormat.format("LICENSETYPE={0}",isNoTimeLimit),
        MessageFormat.format("EXPIREDAY={0}",licenseLimit), //日期采用yyyy-MM-dd日期格式
        MessageFormat.format("MACHINECODE={0}",machineCode),
        ""
    };
 
    //將lic內(nèi)容進(jìn)行混合簽名并寫入內(nèi)容
    StringBuilder sign = new StringBuilder();
    for(String item:liccontent){
      sign.append(item+"yblog");
    }
    liccontent[5] = MessageFormat.format("LICENSESIGN={0}",Encrpt.GetMD5Code(sign.toString()));
    FileUtil.createFileAndWriteLines(licensePath,liccontent);
    //將寫入的內(nèi)容整體加密替換
    String filecontent =FileUtil.readFileToString(licensePath);
    String encrptfilecontent = Encrpt.EncriptWRSA_Pri(filecontent,priavateKeyPath);
    File file = new File(licensePath);
    file.delete();
    FileUtil.createFile(licensePath,encrptfilecontent);
  }

這里我們是將一些信息與特定標(biāo)識進(jìn)行拼接然后加密,使用的是RSA加密,我們使用私鑰加密公鑰解密,保證驗證的開放性與生成證書的私密性,密鑰可以使用java自帶的keytool工具進(jìn)行生成,

教程地址:http://note.youdao.com/noteshare?id=09e2bfc902b21a335a4505f7946a45c9

在lic文件最后我們加上一個LICENSESIGN參數(shù),對其他信息進(jìn)行一次加密,防止信息被篡改,生成文件后再對文本進(jìn)行整體加密

這里生成密鑰的長度為2048而非1024,所以解密塊長度為256,這里需要注意下,公鑰加密方法為,為了方便大家,這里提供下具體加密代碼

private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK=256; 
public static String EncriptWRSA_Pri(String data,String path) throws Exception{
    String encryptData ="";
 
    FileInputStream in = new FileInputStream(path);
    KeyStore ks = KeyStore.getInstance("JKS");// JKS: Java KeyStoreJKS,可以有多種類型
    ks.load(in, "123".toCharArray());
    in.close();
 
    String alias = "yblogkey"; // 記錄的別名
    String pswd = "123"; // 記錄的訪問密碼
    java.security.cert.Certificate cert = ks.getCertificate(alias);
    //獲取私鑰
    PrivateKey privateKey = (PrivateKey) ks.getKey(alias, pswd.toCharArray());
    //私鑰加密
    Cipher cipher = Cipher.getInstance("rsa");
    SecureRandom random = new SecureRandom();
    cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
 
    try {
      // Cipher cipher = Cipher.getInstance("RSA");
      //  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      int length = data.getBytes().length;
      int offset = 0;
      byte[] cache;
      ByteArrayOutputStream outStream = new ByteArrayOutputStream();
      int i = 0;
      while(length - offset > 0){
        if(length - offset > MAX_ENCRYPT_BLOCK){
          cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
        }else{
          cache = cipher.doFinal(data.getBytes(), offset, length - offset);
        }
        outStream.write(cache, 0, cache.length);
        i++;
        offset = i * MAX_ENCRYPT_BLOCK;
      }
      return encode.encode(outStream.toByteArray());
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    }
    return encryptData;
  }
 
 public static String DecriptWithRSA_Pub(String data,String path) throws Exception{
    X509Certificate x509Certificate = (X509Certificate) getCertificate(path);
    // 獲得公鑰
    PublicKey publicKey = x509Certificate.getPublicKey();
 
    Cipher cipher = Cipher.getInstance("rsa");
    SecureRandom random = new SecureRandom();
 
    byte[] bEncrypt = decoder.decodeBuffer(data);
    //公鑰解密
    cipher.init(Cipher.DECRYPT_MODE, publicKey, random);
    String decryptData = "";
    // byte[] plainData = cipher.doFinal(bEncrypt);
    // System.out.println("11111:"+new String(plainData));
    int inputLen = bEncrypt.length;
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int offSet = 0;
    byte[] cache;
    int i = 0;
    // 對數(shù)據(jù)分段解密
    while (inputLen - offSet > 0) {
      if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
        cache = cipher.doFinal(bEncrypt, offSet, MAX_DECRYPT_BLOCK);
      } else {
        cache = cipher.doFinal(bEncrypt, offSet, inputLen - offSet);
      }
      out.write(cache, 0, cache.length);
      i++;
      offSet = i * MAX_DECRYPT_BLOCK;
    }
    byte[] decryptedData = out.toByteArray();
    out.close();
    return new String(decryptedData);
  }

3.驗證lic

我們會在系統(tǒng)中注冊一個攔截器,未通過系統(tǒng)授權(quán)認(rèn)證會自動跳轉(zhuǎn)到lic文件上傳界面,springboot接收文件與常規(guī)java有一些不同,使用的MultipartFile對象,會獲取到上傳文件的數(shù)組,進(jìn)行操作,看下保存上傳lic文件代碼

@RequestMapping(value="/login/licenseauth",method= RequestMethod.POST)
  @ResponseBody
  public Map<Object,Object> licenseauth(MultipartHttpServletRequest multiReq){
    Map<Object,Object> map = new HashMap<Object,Object>();
    try {
      String savePath = ResourceUtils.getURL("src/main/resources/static/lic").getPath();
      MultipartFile file = multiReq.getFile("file");
      String filename = file.getOriginalFilename();
      File uploadfile = new File(savePath + "\\" + filename);
      if (!uploadfile.exists()){
        //獲取item中的上傳文件的輸入流
        InputStream in = file.getInputStream();
        //創(chuàng)建一個文件輸出流
        FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
        //創(chuàng)建一個緩沖區(qū)
        byte buffer[] = new byte[1024];
        //判斷輸入流中的數(shù)據(jù)是否已經(jīng)讀完的標(biāo)識
        int len = 0;
        //循環(huán)將輸入流讀入到緩沖區(qū)當(dāng)中,(len=in.read(buffer))>0就表示in里面還有數(shù)據(jù)
        while((len=in.read(buffer))>0){
          //使用FileOutputStream輸出流將緩沖區(qū)的數(shù)據(jù)寫入到指定的目錄(savePath + "\\" + filename)當(dāng)中
          out.write(buffer, 0, len);
        }
        //關(guān)閉輸入流
        in.close();
        //關(guān)閉輸出流
        out.close();
      }
      map.put("executestatus","1");
 
    }catch (Exception e){
      e.printStackTrace();
      map.put("executestatus","0");
    }
 
    return map;
  }

有了上傳文件,我們就可以通過系統(tǒng)內(nèi)置的公鑰對lic文件的機(jī)器碼,授權(quán)時間進(jìn)行驗證,確定是否能正常訪問系統(tǒng)

public static boolean authLicense() throws Exception{
    boolean isauth = false;
    String pubkpath = ResourceUtils.getURL("src/main/resources/static/lic/").getPath()+"yblog.crt";
    String licpath = ResourceUtils.getURL("src/main/resources/static/lic/").getPath();
    File lic = new File(licpath);
    String[] filelist = lic.list();
    if (filelist.length>0){
      for (int i = 0; i < filelist.length; i++) {
        if (filelist[i].contains(".lic")){
          File readfile = new File(licpath + filelist[i]);
          if (readfile.isFile()) {
            String liccontent = FileUtil.readFileToString(readfile);
            String decriptliccontent = Encrpt.DecriptWithRSA_Pub(liccontent,pubkpath);
            HashMap<String, String> props = genDataFromArrayByte(decriptliccontent.getBytes());
            String licenseid = props.get("LICENSEID");
            String licensename= props.get("LICENSENAME");
            String licensetype = props.get("LICENSETYPE");
            String liclimit = props.get("EXPIREDAY");
            String machinecode = props.get("MACHINECODE");
            String lincensesign = props.get("LICENSESIGN");
            //驗證簽名
            String allinfogroup = "LICENSEID="+licenseid+"yblog"+"LICENSENAME="+licensename+"yblog"+
                "LICENSETYPE="+licensetype+"yblog"+"EXPIREDAY="+liclimit+"yblog"+"MACHINECODE="+machinecode+"yblogyblog";
            if (lincensesign.equals(Encrpt.GetMD5Code(allinfogroup))){
              //驗證機(jī)器碼
              if (getMachineCode().equals(machinecode)){
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                Date bt=new Date();
                Date et=sdf.parse(liclimit);
                //驗證時間
                if(bt.compareTo(et)<=0){
                  isauth = true;
                  System.out.println("注冊文件:"+filelist[i]+",已通過驗證");
                  break;
                }else{
                  System.out.println("證書過期");
                }
              }else{
                System.out.println("機(jī)器碼不一致");
              }
            }else{
              System.out.println("簽名不一致");
            }
          }
        }
      }
    }else{
      System.out.println("未上傳證書");
    }
    return isauth;
  }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot的LogbackLoggingSystem配置加載流程解析

    springboot的LogbackLoggingSystem配置加載流程解析

    這篇文章主要介紹了springboot的LogbackLoggingSystem配置加載流程源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • IDEA 控制臺中文亂碼4種解決方案

    IDEA 控制臺中文亂碼4種解決方案

    IntelliJ IDEA 如果不進(jìn)行相關(guān)設(shè)置,可能會導(dǎo)致控制臺中文亂碼、配置文件中文亂碼等問題,本文主要介紹了IDEA控制臺中文亂碼4種解決方案,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • SpringBoot異步任務(wù)實(shí)現(xiàn)下單校驗庫存的項目實(shí)踐

    SpringBoot異步任務(wù)實(shí)現(xiàn)下單校驗庫存的項目實(shí)踐

    在開發(fā)中,異步任務(wù)應(yīng)用的場景非常的廣泛,本文主要介紹了SpringBoot異步任務(wù)實(shí)現(xiàn)下單校驗庫存的項目實(shí)踐,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Hadoop集成Spring的使用詳細(xì)教程(快速入門大數(shù)據(jù))

    Hadoop集成Spring的使用詳細(xì)教程(快速入門大數(shù)據(jù))

    這篇文章主要介紹了Hadoop集成Spring的使用詳細(xì)教程(快速入門大數(shù)據(jù)),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • SpringMVC學(xué)習(xí)之JSON和全局異常處理詳解

    SpringMVC學(xué)習(xí)之JSON和全局異常處理詳解

    在項目上線之后,往往會出現(xiàn)一些不可預(yù)料的異常信息,對于邏輯性或設(shè)計性問題,開發(fā)人員或者維護(hù)人員需要通過日志,查看異常信息并排除異常,這篇文章主要給大家介紹了關(guān)于SpringMVC學(xué)習(xí)之JSON和全局異常處理的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 詳解JUnit5參數(shù)化測試的幾種方式

    詳解JUnit5參數(shù)化測試的幾種方式

    參數(shù)化測試一直是津津樂道的話題,我們都知道JMeter有四種參數(shù)化方式:用戶自定義變量、用戶參數(shù)、CSV文件、函數(shù)助手,那么JUnit5有哪些參數(shù)化測試的方式呢
    2021-07-07
  • 如何使用@Slf4j和logback-spring.xml搭建日志框架

    如何使用@Slf4j和logback-spring.xml搭建日志框架

    這篇文章主要介紹了如何使用@Slf4j和logback-spring.xml搭建日志框架問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • JavaWeb中轉(zhuǎn)發(fā)與重定向的區(qū)別小結(jié)

    JavaWeb中轉(zhuǎn)發(fā)與重定向的區(qū)別小結(jié)

    轉(zhuǎn)發(fā)和重定向是JavaWeb中常用的兩種頁面跳轉(zhuǎn)方式,它們在實(shí)現(xiàn)上有一些區(qū)別,本文主要介紹了JavaWeb中轉(zhuǎn)發(fā)與重定向的區(qū)別小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • SpringBoot集成canal實(shí)現(xiàn)示例解析

    SpringBoot集成canal實(shí)現(xiàn)示例解析

    這篇文章主要為大家介紹了springboot整合canal的示例實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多多進(jìn)步,早日升職加薪
    2022-02-02
  • Spring Boot Admin的使用詳解(Actuator監(jiān)控接口)

    Spring Boot Admin的使用詳解(Actuator監(jiān)控接口)

    這篇文章主要介紹了Spring Boot Admin的使用詳解(Actuator監(jiān)控接口),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論