首页
社区
课程
招聘
[旧帖] [求助]谁来帮忙分析一下这段代码? 0.00雪花
发表于: 2008-11-14 20:50 2998

[旧帖] [求助]谁来帮忙分析一下这段代码? 0.00雪花

2008-11-14 20:50
2998
这是一款免费注册的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;
    }
}

上面的就是与注册相关的的代码,这种算法好像是不可逆的,这种算法是种什么加密算法?他又是如何根据我提供的序列号给我注册码呢?

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
简单分析一下,不一定对。ABCDMNS全是常数,X是生成的随机数,Y是中间计算结果,Z是提示的序列号,K是注册码

A = 0x30a76d57
B = 0x47e42dbd
C = 0x165ab830
D = 0x2eba946e

M = 0x68ab6813
N = 0x507832a9

S = 0x05f5e103

这里是提示序列号的生成
encrypt(X, S)

Y = B*S*X (mod M)

Z从前往后依次取Y的(十进制)第8,4,7,6,3,2,0,1,9,5位。暂时记作
Z = LookupTable(Y)

上面都是已知的,Z应该会提示给用户的。关键就是用Z算K了
verify(K, Z)

l3 = C*S (mod N)
l4 = K
l5 = (C*S*D)*(C*S*K) (mod N)
l6 = C*Z (mod N)

判断的条件
(C*S*D)*(C*S*K) = C*Z (mod N)

就一个未知数K,解出来就可以了。好像中间那个红色的是普通乘除法,其他的计算都是mod N运算,不知道逆的时候会不会出问题。
K = ( (C*Z) / (C*S*D) ) / (C*S)   (mod N)
2008-11-14 22:30
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢解答,不过K = ( (C*Z) / (C*S*D) ) / (C*S)   (mod N)这个计算的话C*S*D会溢出
2008-11-15 17:42
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这里的*用的是那个multiply()函数,所以C*S*D,应该是
temp = multiply(C, S, N)
result = multiply(temp, D, N)

除法的话不知道你的代码里面有没有,没有的话要自己写了,可以先求multiplicative inverse然后用multiply()求结果。
2008-11-15 18:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
小弟实在太笨,不能领会你的思想。
你说C*S*D,应该是
temp = multiply(C, S, N)
那么C*Z就是
temp=multiply(C,Z,N)吗?
而multiply的三个参数都是int型的,Z若是等于7838231729的话,超出了int的范围。
貌似代码里没有除法,相关代码就是前面的那些了。那么这个除法又该怎么写呢?可否代劳一下?谢谢了。
提供一个序列号和注册码
7838231729序列号
6384394314注册码
2008-11-16 12:00
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
晕啊,我再看看

verify里面用的不是Z,是X
l4=LookupTable(K)
看来还要先要用Z求出来随机数X才行。

不好意思,能力有限实在搞不定,一般来说那个N应该是个质数,0x05f5e103好像不是哦,以前学的密码学知识都忘光了,不知道该怎么处理这种情况了。
2008-11-16 14:19
0
游客
登录 | 注册 方可回帖
返回
//