java软件授权,字符串加密通常写到class类中, 实现一些具体功能, 但是 通过gui反编译以后所有业务逻辑加密授权一览无余,极容易被破解,反编译. 无法保证产权和利益.
下面通过一个案例展示解决方案.
代码源码,通过字符串,日期授权软件相关功能
package com.dongrun.action.autoreport;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* ClassName:TestStrings
* Description:测试 字符串加密方案
* author: Q/V:75238016
* date:2021年11月15日 - 下午5:11:08
*/
public class TestStrings {
//加密串
public static String strpw= "888888888888";
//授权日期
public static String strDate= "2022-08-08 08:08:08";
//测试
public static void main(String[] args) throws Exception {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
//判断当前密码是否一致
if("888888888888".equals(strpw)) {
//执行相关操作
System.out.println("密码验证成功...");
}
//获取当前时间
Date date = new Date();
//判断当前过期时间
if(df.parse(strDate).getTime() > date.getTime()) {
//执行相关操作
System.out.println("时间验证通过...");
}
}
}
gui反编译效果如下图
代码混淆后的效果
混淆后的反编译源码 .
package com.dongrun.action.autoreport;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class TestStrings
{
public static void main(String[] NLCC)
throws Exception
{
String JLCC;
boolean kLCC;
DateFormat mLCC = new SimpleDateFormat(A[b[2]]);
if (G(A[b[3]].equals(strpw)))
System.out.println(A[b[4]]);
Date LLCC = new Date();
if (!(h(f(mLCC.parse(strDate).getTime(), LLCC.getTime()))))
return;
System.out.println(A[b[5]]);
}
private static boolean h(int ???)
{
byte AJCC;
return (??? > 0);
}
private static String b(String EkCC, String dkCC)
{
double wJCC;
String AkCC;
Exception bkCC;
char CkCC;
char dkCC;
char dkCC;
EkCC = new String(Base64.getDecoder().decode(EkCC.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
StringBuilder hkCC = new StringBuilder();
char[] GkCC = dkCC.toCharArray();
int fkCC = b[0];
short ZJCC = EkCC.toCharArray();
boolean yJCC = ZJCC.length;
Exception XJCC = b[0];
while (J(XJCC, yJCC))
{
char LkCC = ZJCC[XJCC];
"".length();
++fkCC;
++XJCC;
"".length();
if (null != null)
return null;
}
return String.valueOf(hkCC);
}
static
{
E();
d();
strpw = A[b[0]];
strDate = A[b[1]];
}
private static String C(String oJCC, String LJCC)
{
short JJCC;
byte kJCC;
boolean LJCC;
boolean LJCC;
try
{
SecretKeySpec RJCC = new SecretKeySpec(MessageDigest.getInstance("MD5").digest(LJCC.getBytes(StandardCharsets.UTF_8)), "Blowfish");
Cipher qJCC = Cipher.getInstance("Blowfish");
qJCC.init(b[2], RJCC);
return new String(qJCC.doFinal(Base64.getDecoder().decode(oJCC.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8);
}
catch (Exception PJCC)
{
PJCC.printStackTrace();
}
return null;
}
private static String A(String ALCC, String ZkCC)
{
char VkCC;
Exception wkCC;
String ZkCC;
String ZkCC;
try
{
SecretKeySpec dLCC = new SecretKeySpec(Arrays.copyOf(MessageDigest.getInstance("MD5").digest(ZkCC.getBytes(StandardCharsets.UTF_8)), b[7]), "DES");
Cipher CLCC = Cipher.getInstance("DES");
CLCC.init(b[2], dLCC);
return new String(CLCC.doFinal(Base64.getDecoder().decode(ALCC.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8);
}
catch (Exception bLCC)
{
bLCC.printStackTrace();
}
return null;
}
private static void d()
{
A = new String[b[6]];
A[b[0]] = A("qHu8wLLDF3GtZHy0018HAw==", "tVOKu");
A[b[1]] = b("f0F4QHh9SWdCbW1BckhldUt6Sg==", "MqJrU");
A[b[2]] = C("uX8Ds2zyr8EqcR6UE9pyWlqyUMsAaDgO", "VGtVr");
A[b[3]] = b("QlJbXE5CUltcTkJS", "zjcdv");
A[b[4]] = A("JktDF9fl3OwDkhnixRjda/Z9EUCprgtJ", "SfSkl");
A[b[5]] = A("JTPA6jQSVMwNKBts2Mfou3sEhcAMbgpN", "JMCOI");
}
private static boolean G(int ???)
{
float CJCC;
return (??? != 0);
}
private static void E()
{
b = new int[8];
b[0] = ((36 + 67 - -22 + 6 ^ 67 + 63 - -11 + 38) & (0xEC ^ 0xC3 ^ 0x8C ^ 0x93 ^ -" ".length()));
b[1] = " ".length();
b[2] = " ".length();
b[3] = " ".length();
b[4] = (0x1E ^ 0x1A);
b[5] = (0x6 ^ 0x3);
b[6] = (0xC3 ^ 0xC5);
b[7] = (47 + 112 - 69 + 76 ^ 164 + 167 - 330 + 173);
}
private static int f(long paramLong1, long paramLong2)
{
return (paramLong1 < paramLong2);
}
private static boolean J(int ???, int arg1)
{
int i;
byte EJCC;
return (??? < i);
}
}
复制回项目完全没发运行,无法编译 破解
从上面的案例可以看出,字节码混淆后,反编译也无法破解 密码,日期授权,核心业务流程,达到保护软件的目的
需要加密,制定化的,欢迎大家交流学习!
qq/wx : 75238016