怎么使用java生成激活码和密钥(java,开发技术)

时间:2024-05-06 05:23:12 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

解密与加密设计思路

加密:
采用AES对称加密、解密
7位数: 32进制序列(4位) + 密钥类别(2位)+ 有效时长(1位)
加密后密钥为11位
4位数:前三位,先获取一个(0到2500)的随机数,然后再乘11,接着转换为三位的32进制数,然后最后一位是(机器版本号),
最后 3位+1位 生成4位数
预想15位密钥
11位+4位
接着密钥打乱顺序混淆

混淆策略:先分别获取激活码的奇数位和偶数位,然后将奇数位和偶数位拼接获得混淆后的激活码
奇数位+偶数位

解密:
(1) 解除混淆(将混淆后的激活码进行重组复原)
(2) 校验密钥后四位;校验成功继续下一步操作,校验失败密钥无效
(3) 只有校验成功才能对前十一位密钥进行解密;校验失败密钥无效
(4) 解密成功,说明是有效密钥,获取密钥信息,根据信息对客户端进行相应操作;解密失败,说明密钥无效
(5) 无论解密成功与否给服务端发请求,通知服务端,然后进行相应的操作和记录

其中:密钥类别(2位)可以用来表示该激活码用来激活哪些设备或者哪些平台(如01表示某个平台,02表示某个app),时长(1位)用来表示该激活码的有效时长(如0表示永久、1表示7天、2表示30天等)
注意:前7位数加密后为11位,表示该激活码可以生成的个数;后4位数为随机数 * 11转32进制和混淆策略是为了激活码的加密性,用来校验该激活码是否有效

因此,该激活码的加密主要体现在三个地方:

  • 混淆策略

  • 32禁止转18进制后能否被11整除

  • AES对称加密、解密

解密与加密工具类

CDKeyUtil.java

importjava.util.Random;/***Createdbytao.*Date:2021/6/2816:43*描述:*/publicclassCDKeyUtil{//机器版本号/***激活码生成方法**@paramcategory密钥类别(固定两位数字)*@paramdeadline使用期限(固定一位字符)*@return返回的激活码*/publicstaticStringcreateCDkey(Stringcategory,Stringdeadline,StringmachineVersion)throwsException{StringCDKey="";//1.获取前四位Stringsequence=getSequence();//2.生成前七位Stringplaintext=sequence+category+deadline;//3.对明文进行加密CDKey=CDKeyEncryptUtils.AESencrypt(plaintext).substring(0,11);//4.获取后四位StringrulesSequence=CDKeyUtil.getRulesSequence(machineVersion);//5.混淆操作CDKey=CDKey+rulesSequence;CDKey=confusion(CDKey);//6.得到激活码returnCDKey;}/***激活码解码方法**@paramCDKey激活码*@return返回激活码明文*/publicstaticStringdeCDkey(StringCDKey,StringmachineVersion)throwsException{//1.解除混淆StringdeConfusion=deConfusion(CDKey);//2.提取后四位序列(第1位版本号,后三位校验其规则)Stringsequence=deConfusion.substring(deConfusion.length()-4);//3.获取后三位序列并且转为10进制,和版本号StringrandomInt=sequence.substring(1);Stringversion=sequence.substring(0,1);intto10=Integer.parseInt(change32To10(randomInt));//4.根据既定规则校验激活码是否正确if(to10%11==0&&version.equals(machineVersion)){//1.如果后四位序列校验正确,则对激活码进行解密操作StringsecretKey=deConfusion.substring(0,11);Stringcode="";try{code=CDKeyEncryptUtils.AESdecrypt(secretKey);}catch(Exceptione){e.printStackTrace();return"激活码错误";}returncode;}else{return"激活码错误";}}/***获得激活码前四位序列方法**@return返回激活码前四位序列*/publicstaticStringgetSequence(){Stringsequence="";//1.获取随机数intrandomInt=getRandomInt();//2.转32进制Stringto32=change10To32(randomInt+"");//3.补全四位intlen=to32.length();if(len<4){for(inti=0;i<4-len;i++){to32="0"+to32;}}sequence=to32;returnsequence;}/***获得激活码后四位规则序列方法**@parammachineVersion机器版本号*@return返回激活码后四位规则序列*/publicstaticStringgetRulesSequence(StringmachineVersion){StringrulesSequence;//1.按照规则获取前三位/*intrandomInt=newRandom().nextInt(8);StringrandomStr=randomInt+""+(randomInt+1)+(randomInt+2);*///1.按照规则获取前三位intrandomInt=newRandom().nextInt(2500);StringrandomStr=(randomInt*11)+"";//2.转32进制Stringto32=change10To32(randomStr);//3.补全三位intlen=to32.length();if(len<3){for(inti=0;i<3-len;i++){to32="0"+to32;}}//4.拼接第四位rulesSequence=machineVersion+to32;returnrulesSequence;}/***激活码混淆方法*奇数位+偶数位**@return返回激活码混淆后的序列*/publicstaticStringconfusion(StringCDKey){StringdeCDKey="";//1.获取奇数位字串Stringodd="";for(inti=0;i<CDKey.length();i=i+2){odd=odd+CDKey.charAt(i);}//2.获取偶数位字串Stringeven="";for(inti=1;i<CDKey.length();i=i+2){even=even+CDKey.charAt(i);}//3.拼接deCDKey=odd+even;returndeCDKey;}/***激活码解除混淆方法**@return返回激活码解除混淆后的序列*/publicstaticStringdeConfusion(StringdeCDKey){StringCDKey="";//1.拆分intoddCount=(deCDKey.length()/2)+(deCDKey.length()%2);Stringodd=deCDKey.substring(0,oddCount);Stringeven=deCDKey.substring(oddCount);//2.复原激活码if(odd.length()==even.length()){for(inti=0;i<odd.length();i++){CDKey=CDKey+odd.charAt(i)+even.charAt(i);}}else{for(inti=0;i<even.length();i++){CDKey=CDKey+odd.charAt(i)+even.charAt(i);}CDKey=CDKey+odd.charAt(odd.length()-1);}returnCDKey;}/***10进制转32进制的方法*num要转换的数from源数的进制to要转换成的进制**@paramnum10进制(字符串)*@return转换结果的32进制字符串*/publicstaticStringchange10To32(Stringnum){intfrom=10;intto=32;returnnewjava.math.BigInteger(num,from).toString(to);}/***32进制转10进制的方法*num要转换的数from源数的进制to要转换成的进制**@paramnum10进制(字符串)*@return转换结果的10进制字符串*/publicstaticStringchange32To10(Stringnum){intf=32;intt=10;returnnewjava.math.BigInteger(num,f).toString(t);}/***生成[min,max]之间的随机整数*min最小整数(固定0)*max最大整数(固定1000000)**@return返回min———max之间的随机数*@authortao*/publicstaticintgetRandomInt(){intmin=0;intmax=1000000;returnnewRandom().nextInt(max)%(max-min+1)+min;}/**枚举日期,返回天数*/publicstaticintduetimeEnum(Stringcode){switch(code){case"0":return36500;case"1":return7;case"2":return30;case"3":return90;case"4":return180;case"5":return365;default:return30;}}}

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

importorg.apache.commons.codec.binary.Base64;importjavax.crypto.Cipher;importjavax.crypto.spec.IvParameterSpec;importjavax.crypto.spec.SecretKeySpec;/***Createdbytao.*Date:2021/6/2816:37*描述:*/publicclassCDKeyEncryptUtils{ //--------------AES--------------- privatestaticfinalStringKEY="12055296";//密匙,必须16位 privatestaticfinalStringOFFSET="12055296";//偏移量 privatestaticfinalStringENCODING="UTF-8";//编码 privatestaticfinalStringALGORITHM="DES";//算法 privatestaticfinalStringCIPHER_ALGORITHM="DES/CBC/PKCS5Padding";//默认的加密算法,CBC模式 publicstaticStringAESencrypt(Stringdata)throwsException{ //指定算法、获取Cipher对象(DES/CBC/PKCS5Padding:算法为,工作模式,填充模式) Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); //根据自定义的加密密匙和算法模式初始化密钥规范 SecretKeySpecskeySpec=newSecretKeySpec(KEY.getBytes("ASCII"),ALGORITHM); //CBC模式偏移量IV IvParameterSpeciv=newIvParameterSpec(OFFSET.getBytes()); //初始化加密模式 cipher.init(Cipher.ENCRYPT_MODE,skeySpec,iv); //单部分加密结束,重置Cipher byte[]encrypted=cipher.doFinal(data.getBytes(ENCODING)); //加密后再使用BASE64做转码 returnnewBase64().encodeToString(encrypted); } /** *AES解密 * *@paramdata *@returnString *@authortao *@date2021-6-1516:46:07 */ publicstaticStringAESdecrypt(Stringdata)throwsException{ //指定算法、获取Cipher对象(DES/CBC/PKCS5Padding:算法为,工作模式,填充模式) Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); //根据自定义的加密密匙和算法模式初始化密钥规范 SecretKeySpecskeySpec=newSecretKeySpec(KEY.getBytes("ASCII"),ALGORITHM); //CBC模式偏移量IV IvParameterSpeciv=newIvParameterSpec(OFFSET.getBytes()); //初始化解密模式 cipher.init(Cipher.DECRYPT_MODE,skeySpec,iv); //先用base64解码 byte[]buffer=newBase64().decode(data); //单部分加密结束,重置Cipher byte[]encrypted=cipher.doFinal(buffer); returnnewString(encrypted,ENCODING); }}

其中AES的key为12055296,设置为8位,则机密后的密文则为11位,加密算法为 “DES”

激活码生成测试

publicstaticvoidmain(String[]args)throwsException{for(inti=0;i<10;i++){StringCDKey=CDKeyUtil.createCDkey("01","0","1");System.out.println("激活码:"+CDKey);StringdeCDkey=CDKeyUtil.deCDkey(CDKey,"1");System.out.println("激活码解密:"+deCDkey);}}

执行结果:

怎么使用java生成激活码和密钥

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:怎么使用java生成激活码和密钥的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:怎么利用Python绘制科赫曲线下一篇:

22 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18