最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用java生成激活碼和密鑰的方法

 更新時(shí)間:2022年05月13日 14:29:41   作者:不愿意做魚的小鯨魚  
本文主要介紹了java生成激活碼和密鑰的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

解密與加密設(shè)計(jì)思路

加密:
采用AES對稱加密、解密
7位數(shù): 32進(jìn)制序列(4位) + 密鑰類別(2位)+ 有效時(shí)長(1位)
加密后密鑰為11位
4位數(shù):前三位,先獲取一個(gè)(0到2500)的隨機(jī)數(shù),然后再乘11,接著轉(zhuǎn)換為三位的32進(jìn)制數(shù),然后最后一位是(機(jī)器版本號),
最后 3位+1位 生成4位數(shù)
預(yù)想15位密鑰
11位+4位
接著密鑰打亂順序混淆

混淆策略:先分別獲取激活碼的奇數(shù)位和偶數(shù)位,然后將奇數(shù)位和偶數(shù)位拼接獲得混淆后的激活碼
奇數(shù)位+偶數(shù)位

解密:
(1) 解除混淆(將混淆后的激活碼進(jìn)行重組復(fù)原)
(2) 校驗(yàn)密鑰后四位;校驗(yàn)成功繼續(xù)下一步操作,校驗(yàn)失敗密鑰無效
(3) 只有校驗(yàn)成功才能對前十一位密鑰進(jìn)行解密;校驗(yàn)失敗密鑰無效
(4) 解密成功,說明是有效密鑰,獲取密鑰信息,根據(jù)信息對客戶端進(jìn)行相應(yīng)操作;解密失敗,說明密鑰無效
(5) 無論解密成功與否給服務(wù)端發(fā)請求,通知服務(wù)端,然后進(jìn)行相應(yīng)的操作和記錄

其中:密鑰類別(2位)可以用來表示該激活碼用來激活哪些設(shè)備或者哪些平臺(如01表示某個(gè)平臺,02表示某個(gè)app),時(shí)長(1位)用來表示該激活碼的有效時(shí)長(如0表示永久、1表示7天、2表示30天等)
注意:前7位數(shù)加密后為11位,表示該激活碼可以生成的個(gè)數(shù);后4位數(shù)為隨機(jī)數(shù) * 11轉(zhuǎn)32進(jìn)制和混淆策略是為了激活碼的加密性,用來校驗(yàn)該激活碼是否有效

因此,該激活碼的加密主要體現(xiàn)在三個(gè)地方:

  • 混淆策略
  • 32禁止轉(zhuǎn)18進(jìn)制后能否被11整除
  • AES對稱加密、解密

解密與加密工具類

CDKeyUtil.java

import java.util.Random;

/**
 * Created by tao.
 * Date: 2021/6/28 16:43
 * 描述:
 */
public class CDKeyUtil {

    //機(jī)器版本號

    /**
     * 激活碼生成方法
     *
     * @param category 密鑰類別(固定兩位數(shù)字)
     * @param deadline 使用期限(固定一位字符)
     * @return 返回的激活碼
     */
    public static String createCDkey(String category, String deadline, String machineVersion) throws Exception {
        String CDKey = "";
        //1. 獲取前四位
        String sequence = getSequence();
        //2. 生成前七位
        String plaintext = sequence + category + deadline;
        //3.對明文進(jìn)行加密
        CDKey = CDKeyEncryptUtils.AESencrypt(plaintext).substring(0, 11);
        //4.獲取后四位
        String rulesSequence = CDKeyUtil.getRulesSequence(machineVersion);
        //5.混淆操作
        CDKey = CDKey + rulesSequence;
        CDKey = confusion(CDKey);
        //6.得到激活碼
        return CDKey;
    }


    /**
     * 激活碼解碼方法
     *
     * @param CDKey 激活碼
     * @return 返回激活碼明文
     */
    public static String deCDkey(String CDKey, String machineVersion) throws Exception {
        //1. 解除混淆
        String deConfusion = deConfusion(CDKey);
        //2. 提取后四位序列(第1位版本號,后三位校驗(yàn)其規(guī)則)
        String sequence = deConfusion.substring(deConfusion.length() - 4);
        //3. 獲取后三位序列并且轉(zhuǎn)為10進(jìn)制,和版本號
        String randomInt = sequence.substring(1);
        String version = sequence.substring(0, 1);
        int to10 = Integer.parseInt(change32To10(randomInt));
        //4. 根據(jù)既定規(guī)則校驗(yàn)激活碼是否正確
        if (to10 % 11 == 0 && version.equals(machineVersion)) {
            //1. 如果后四位序列校驗(yàn)正確,則對激活碼進(jìn)行解密操作
            String secretKey = deConfusion.substring(0, 11);
            String code = "";
            try {
                code = CDKeyEncryptUtils.AESdecrypt(secretKey);
            } catch (Exception e) {
                e.printStackTrace();
                return "激活碼錯(cuò)誤";
            }
            return code;
        } else {
            return "激活碼錯(cuò)誤";
        }

    }


    /**
     * 獲得激活碼前四位序列方法
     *
     * @return 返回激活碼前四位序列
     */
    public static String getSequence() {
        String sequence = "";
        //1. 獲取隨機(jī)數(shù)
        int randomInt = getRandomInt();
        //2. 轉(zhuǎn)32進(jìn)制
        String to32 = change10To32(randomInt + "");
        //3. 補(bǔ)全四位
        int len = to32.length();
        if (len < 4) {
            for (int i = 0; i < 4 - len; i++) {
                to32 = "0" + to32;
            }
        }
        sequence = to32;
        return sequence;
    }

    /**
     * 獲得激活碼后四位規(guī)則序列方法
     *
     * @param machineVersion 機(jī)器版本號
     * @return 返回激活碼后四位規(guī)則序列
     */
    public static String getRulesSequence(String machineVersion) {
        String rulesSequence;
        //1. 按照規(guī)則獲取前三位
        /*int randomInt = new Random().nextInt(8);
        String randomStr = randomInt + "" + (randomInt + 1) + (randomInt + 2);*/

        //1. 按照規(guī)則獲取前三位
        int randomInt = new Random().nextInt(2500);
        String randomStr = (randomInt * 11) + "";
        //2. 轉(zhuǎn)32進(jìn)制
        String to32 = change10To32(randomStr);
        //3. 補(bǔ)全三位
        int len = to32.length();
        if (len < 3) {
            for (int i = 0; i < 3 - len; i++) {
                to32 = "0" + to32;
            }
        }
        //4.拼接第四位
        rulesSequence = machineVersion + to32;
        return rulesSequence;
    }

    /**
     * 激活碼混淆方法
     * 奇數(shù)位+偶數(shù)位
     *
     * @return 返回激活碼混淆后的序列
     */
    public static String confusion(String CDKey) {
        String deCDKey = "";
        //1.獲取奇數(shù)位字串
        String odd = "";
        for (int i = 0; i < CDKey.length(); i = i + 2) {
            odd = odd + CDKey.charAt(i);
        }
        //2.獲取偶數(shù)位字串
        String even = "";
        for (int i = 1; i < CDKey.length(); i = i + 2) {
            even = even + CDKey.charAt(i);
        }
        //3.拼接
        deCDKey = odd + even;
        return deCDKey;
    }

    /**
     * 激活碼解除混淆方法
     *
     * @return 返回激活碼解除混淆后的序列
     */
    public static String deConfusion(String deCDKey) {
        String CDKey = "";
        //1. 拆分
        int oddCount = (deCDKey.length() / 2) + (deCDKey.length() % 2);
        String odd = deCDKey.substring(0, oddCount);
        String even = deCDKey.substring(oddCount);
        //2. 復(fù)原激活碼
        if (odd.length() == even.length()) {
            for (int i = 0; i < odd.length(); i++) {
                CDKey = CDKey + odd.charAt(i) + even.charAt(i);
            }
        } else {
            for (int i = 0; i < even.length(); i++) {
                CDKey = CDKey + odd.charAt(i) + even.charAt(i);
            }
            CDKey = CDKey + odd.charAt(odd.length() - 1);
        }
        return CDKey;
    }

    /**
     * 10進(jìn)制轉(zhuǎn)32進(jìn)制的方法
     * num 要轉(zhuǎn)換的數(shù) from源數(shù)的進(jìn)制 to要轉(zhuǎn)換成的進(jìn)制
     *
     * @param num 10進(jìn)制(字符串)
     * @return 轉(zhuǎn)換結(jié)果的32進(jìn)制字符串
     */
    public static String change10To32(String num) {
        int from = 10;
        int to = 32;
        return new java.math.BigInteger(num, from).toString(to);
    }

    /**
     * 32進(jìn)制轉(zhuǎn)10進(jìn)制的方法
     * num 要轉(zhuǎn)換的數(shù) from源數(shù)的進(jìn)制 to要轉(zhuǎn)換成的進(jìn)制
     *
     * @param num 10進(jìn)制(字符串)
     * @return 轉(zhuǎn)換結(jié)果的10進(jìn)制字符串
     */
    public static String change32To10(String num) {
        int f = 32;
        int t = 10;
        return new java.math.BigInteger(num, f).toString(t);
    }

    /**
     * 生成[min, max]之間的隨機(jī)整數(shù)
     * min 最小整數(shù)(固定0)
     * max 最大整數(shù)(固定1000000)
     *
     * @return 返回min———max之間的隨機(jī)數(shù)
     * @author tao
     */
    public static int getRandomInt() {
        int min = 0;
        int max = 1000000;
        return new Random().nextInt(max) % (max - min + 1) + min;
    }


    /*
     * 枚舉日期,返回天數(shù)
     */
    public static int duetimeEnum(String code) {
        switch (code) {
            case "0":
                return 36500;
            case "1":
                return 7;
            case "2":
                return 30;
            case "3":
                return 90;
            case "4":
                return 180;
            case "5":
                return 365;
            default:
                return 30;
        }
    }
}

其中用到AES加密和解密:CDKeyEncryptUtils.java

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by tao.
 * Date: 2021/6/28 16:37
 * 描述:
 */
public class CDKeyEncryptUtils {
	    //--------------AES---------------
	    private static final String KEY = "12055296";  // 密匙,必須16位
	    private static final String OFFSET = "12055296"; // 偏移量
	    private static final String ENCODING = "UTF-8"; // 編碼
	    private static final String ALGORITHM = "DES"; //算法
	    private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding"; // 默認(rèn)的加密算法,CBC模式


	    public static String AESencrypt(String data) throws Exception {
	        //指定算法、獲取Cipher對象(DES/CBC/PKCS5Padding:算法為,工作模式,填充模式)
	        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
	        //根據(jù)自定義的加密密匙和算法模式初始化密鑰規(guī)范
	        SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
	        //CBC模式偏移量IV
	        IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes());
	        //初始化加密模式
	        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
	        //單部分加密結(jié)束,重置Cipher
	        byte[] encrypted = cipher.doFinal(data.getBytes(ENCODING));
	        //加密后再使用BASE64做轉(zhuǎn)碼
	        return new Base64().encodeToString(encrypted);
	    }

	    /**
	     * AES解密
	     *
	     * @param data
	     * @return String
	     * @author tao
	     * @date 2021-6-15 16:46:07
	     */
	    public static String AESdecrypt(String data) throws Exception {
	        //指定算法、獲取Cipher對象(DES/CBC/PKCS5Padding:算法為,工作模式,填充模式)
	        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
	        //根據(jù)自定義的加密密匙和算法模式初始化密鑰規(guī)范
	        SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
	        //CBC模式偏移量IV
	        IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes());
	        //初始化解密模式
	        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
	        //先用base64解碼
	        byte[] buffer = new Base64().decode(data);
	        //單部分加密結(jié)束,重置Cipher
	        byte[] encrypted = cipher.doFinal(buffer);
	        return new String(encrypted, ENCODING);
	    }
}

其中AES的key為12055296,設(shè)置為8位,則機(jī)密后的密文則為11位,加密算法為 “DES”

激活碼生成測試

 public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10; i++) {
            String CDKey = CDKeyUtil.createCDkey("01", "0", "1");
            System.out.println("激活碼:" + CDKey);
            String deCDkey = CDKeyUtil.deCDkey(CDKey, "1");
            System.out.println("激活碼解密:" + deCDkey);
        }

    }

執(zhí)行結(jié)果:

在這里插入圖片描述

 到此這篇關(guān)于使用java生成激活碼和密鑰的方法的文章就介紹到這了,更多相關(guān)java生成激活碼和密鑰內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java計(jì)算值所占的百分比,結(jié)果為100%問題

    java計(jì)算值所占的百分比,結(jié)果為100%問題

    這篇文章主要介紹了java計(jì)算值所占的百分比,結(jié)果為100%問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Spring AbstractRoutingDatasource 動態(tài)數(shù)據(jù)源的實(shí)例講解

    Spring AbstractRoutingDatasource 動態(tài)數(shù)據(jù)源的實(shí)例講解

    本文介紹如何使用 Spring AbstractRoutingDatasource 基于上下文動態(tài)切換數(shù)據(jù)源,因此我們會讓查找數(shù)據(jù)源邏輯獨(dú)立于數(shù)據(jù)訪問之外
    2021-07-07
  • Java中Exception和Error的區(qū)別詳解

    Java中Exception和Error的區(qū)別詳解

    這篇文章主要介紹了Java中Exception和Error的區(qū)別詳解,通過類的關(guān)系分析兩者的區(qū)別與應(yīng)用場景,包含代碼實(shí)例,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Springboot內(nèi)嵌SQLite配置使用詳解

    Springboot內(nèi)嵌SQLite配置使用詳解

    這篇文章主要介紹了Springboot內(nèi)嵌SQLite配置使用詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • springboot升級Tomcat版本的方法示例

    springboot升級Tomcat版本的方法示例

    本文主要介紹了springboot升級Tomcat版本的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • java如何解析/讀取xml文件

    java如何解析/讀取xml文件

    這篇文章主要為大家詳細(xì)介紹了java如何解析/讀取xml文件的方法,感興趣的小伙伴們可以參考一下
    2016-03-03
  • springboot]logback日志框架配置教程

    springboot]logback日志框架配置教程

    這篇文章主要介紹了springboot]logback日志框架配置,logback既可以通過application配置文件進(jìn)行日志的配置,又可以通過logback-spring.xml進(jìn)行日志的配置,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-04-04
  • SpringMVC攔截器零基礎(chǔ)掌握

    SpringMVC攔截器零基礎(chǔ)掌握

    攔截器(Interceptor)是一種動態(tài)攔截方法調(diào)用的機(jī)制,在SpringMVC中動態(tài)攔截控制器方法的執(zhí)行。本文將詳細(xì)講講SpringMVC中攔截器的概念及入門案例,感興趣的可以嘗試一下
    2023-03-03
  • Java線程變量ThreadLocal詳細(xì)解讀

    Java線程變量ThreadLocal詳細(xì)解讀

    這篇文章主要介紹了Java線程變量ThreadLocal詳細(xì)解讀,多線程訪問同一個(gè)變量的時(shí)候,很容易出現(xiàn)問題,特別是多線程對一個(gè)共享變量進(jìn)行寫入的時(shí)候,為了線程的安全在進(jìn)行數(shù)據(jù)寫入時(shí)候會進(jìn)行數(shù)據(jù)的同步,需要的朋友可以參考下
    2024-01-01
  • Base64與File之間的相互轉(zhuǎn)化方式

    Base64與File之間的相互轉(zhuǎn)化方式

    這篇文章主要介紹了Base64與File之間的相互轉(zhuǎn)化方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評論

洞头县| 斗六市| 北宁市| 澳门| 澄城县| 龙胜| 宣汉县| 那曲县| 博客| 陈巴尔虎旗| 太仆寺旗| 清新县| 舟曲县| 邵武市| 项城市| 南宁市| 巴东县| 长沙市| 武乡县| 泰兴市| 宜春市| 双辽市| 耒阳市| 法库县| 吉木萨尔县| 曲阳县| 巴青县| 保定市| 得荣县| 邯郸县| 岚皋县| 枣庄市| 黄骅市| 瑞昌市| 成安县| 扬中市| 随州市| 米泉市| 舟山市| 合阳县| 阳泉市|