这是一款免费注册的jar手机软件的注册代码,注册码获取的方式是在其论坛上提供序列号,他会根据你的序列号给出注册码,分析了下与注册有关的代码,有些地方不太明白,主要问题是这种算法是种什么算法?他怎么根据提供的序列号算出注册码?
下面这个是某个类的一个方法,作用是生成序列号并保存在记录中:
public static void createSerial()
{
int i = 0x5f5e103;
Random random = new Random();
StringBuffer stringbuffer = new StringBuffer();
int j = 0;
boolean flag = false;
for(int l = 0; l < 8; l++)
//这个循环生成一个八位的随机数字
{
int k = random.nextInt() % 9;
if(k <= 0)
k += 9;
j = 10 * j + k % 9;
}
stringbuffer.append(j);
//把八位的数字转换成字符
String s = Registeration.encrypt(j, i);
//调用regsteration类的encrypt方法生成一个十位数的序列号,具体代码在下面
byte abyte0[] = stringbuffer.toString().getBytes();
setRecord("runtimeinfo", 3, abyte0, 0, abyte0.length);
//把生成的八位随机数保存在记录里
abyte0 = s.getBytes();
setRecord("runtimeinfo", 4, abyte0, 0, abyte0.length);
//把生成的序列号保存在记录里
}
以下是regsteration类的具体代码:
public class Registeration
{
public Registeration()
{
}
public static String register(String s)
//验证注册码的合法性 {
int i = Integer.parseInt(new String(DBTool.getRecord("runtimeinfo", 3)));
if(verify(s, i))
{
DBTool.setRecord("runtimeinfo", 5, s.getBytes());
RuntimeInfo.have_registered = 1;
RuntimeInfo.saveData();
return " 操作成功完成!";
} else
{
return " 注册码不合法,注册失败!";
}
}
public static String encrypt(int i, int j)
//上面所说的,根据生成的八位随机数来返回一个十位的数
{
long l = 0x68ab6813L;
long l1 = 0x30a76d57L;
long l2 = 0x47e42dbdL;
long l3 = 1L;
long l4 = 1L;
StringBuffer stringbuffer = null;
l3 = multiply((int)l1, j, (int)l);
l4 = multiply((int)l2, j, (int)l);
l4 = (l4 * (long)i) % l;
if(l3 < 0L)
l3 += l;
if(l4 < 0L)
l4 += l;
String s = "0000000000" + l4;
s = s.substring(s.length() - 10);
stringbuffer = new StringBuffer();
for(int k = 0; k < 10; k++)
stringbuffer.append(s.charAt(n[k]));
return stringbuffer.toString();
}
public static boolean verify(String s, int i)
//验证序列号是否合法的方法,其中参数s是输入的序列号,i是前面生成的八位的随机数
{
long l = 0x507832a9L;
long l1 = 0x165ab830L;
long l2 = 0x2eba946eL;
long l3 = 0L;
long l4 = 0L;
StringBuffer stringbuffer = new StringBuffer();
for(int j = 0; j < 10; j++)
stringbuffer.append(s.charAt(n[j]));
s = stringbuffer.toString();
l3 = multiply((int)l1, 0x5f5e103, (int)l);
l4 = Long.parseLong(s);
boolean flag = false;
long l5 = 0L;
long l6 = 0L;
l5 = multiply((int)l2, (int)l3, (int)l);
l5 = (l5 * (long)multiply((int)l3, (int)l4, (int)l)) % l;
l6 = multiply((int)l1, i, (int)l);
if(l5 < 0L)
l1 += l;
if(l6 < 0L)
l6 += l;
if(l5 == l6)
//这里为什么通过上面的计算会相等呢??
flag = true;
return flag;
}
public static int multiply(int i, int j, int k)
{
long l = 1L;
boolean flag = false;
for(int i1 = 1; i1 < 32; i1++)
{
byte byte0 = (byte)((j >> 31 - i1) % 2);
l = (l * l) % (long)k;
if(byte0 == 1)
l = (l * (long)i) % (long)k;
}
if(l < 0L)
l += k;
return (int)l;
}
static int n[];
static
{
n = new int[10];
n[0] = 8;
n[1] = 4;
n[2] = 7;
n[3] = 6;
n[4] = 3;
n[5] = 2;
n[6] = 0;
n[7] = 1;
n[8] = 9;
n[9] = 5;
}
}
上面的就是与注册相关的的代码,这种算法好像是不可逆的,这种算法是种什么加密算法?他又是如何根据我提供的序列号给我注册码呢?
[课程]Linux pwn 探索篇!