首页
社区
课程
招聘
[旧帖] 动态规划用于加密初探(1)(2) 0.00雪花
2010-3-4 12:21 2584

[旧帖] 动态规划用于加密初探(1)(2) 0.00雪花

2010-3-4 12:21
2584
1,在本文中,我试图将算法中经典的动态规划设计用于软件加密,可结合其他加密算法共同使用。
2,以C++实现,不进行API调用,主要关注算法在软件保护方面的灵活运用。
3,欢迎各位进行破解尝试,源代码附有示例姓名与序列号。
4,原创拙作,水平有限,欢迎各位给予指点。
                        ——Green Tsai


/*
  Name: 动态规划算法用于软件加密初探(1) 
  Copyright: @Green Tsai
  Author: Green Tsai
  Date: 04-03-10 12:11
  Description: 
		1,思路与想法:本程序试图将动态规划算法用于软件加密,并用动态规划中最经典的LIS(Longest Increasing Subsequence)
	问题作一示例。 
		2,对软件进行非明码比较加密,避免一般的逆向破解。
		3,示例姓名:kanxue,序列号:xbayczhfea80。
*/

#include <cstdlib>
#include <iostream>

using namespace std;

int Solve(char *a,int n);
bool CheckName(char *name,int len);
bool CheckSerial(char *serial,int len);
bool CheckLen(int a,int b);

int main(int argc,char *argv[])
{
	bool ok=false;	
	while(ok==false)
	{
		char name[30],serial[30];
		cout<<"Please input your name:"<<endl;
		cin>>name;
		cout<<"Please input your serial number:"<<endl;
		cin>>serial;
		int x=Solve(name,strlen(name));
    	int y=Solve(serial,strlen(serial));
    	
    	// cout<<"strlen:"<<strlen(name)<<" "<<strlen(serial)<<endl;
    	// cout<<x<<" "<<y<<endl;
    	
    	if(CheckName(name,strlen(name)) && CheckSerial(serial,strlen(serial)) && (2*strlen(name)==strlen(serial)) && (x==y) && (x>=3))
		{
			ok=true;
			cout<<"Congratulations!"<<endl;
			cout<<endl;
		}
		else
		{
			cout<<"Sorry!"<<endl;
			cout<<endl;
		}  
	}
	
	system("PAUSE");
	return 0;   
}

int Solve(char *a,int n)   
{   
	int dp[30];	
    dp[0]=1;   
    int ans=0;   
    for(int i=1;i<n;i++)   
    {   
        int max=0;   
        for(int j=0;j<i;j++)   
        {   
            if(a[i]>=a[j] && max<dp[j])   
                max=dp[j];   
        }   
        dp[i]=max+1;  
		                   
        if(ans<dp[i])     
            ans=dp[i];      
    }   
    return ans;   
}  

bool CheckName(char *name,int len)
{
	if(len>=3 && len<=10)
		return true;
	else
		return false;
}

bool CheckSerial(char *serial,int len)
{
	if(len>=6 && len<=20)
		return true;
	else
		return false;
}


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

上传的附件:
收藏
点赞6
打赏
分享
最新回复 (5)
雪    币: 424
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
resty 2 2010-3-4 12:52
2
0
先鼓励一下,不过这个还是比较简单的了,可以考虑以下几点:
1.先讲讲产生序列号的方法:
   比如我用用户名resty,那么可行的密码有
   restyRESTY,resty54321等等哪怕是什么8888777766等,虽然没有明文比较,但对应可用的序列号太多了。
2.使用LIS的算法太简单,O(n^2)的DP,哪怕是反汇编也一眼就看完了,建议可以改进成O(nlogn)的LIS算法(有DP和贪心两种)。并且可以考虑把LIS计算过程中的方案也求出来,并用到加密上,就会强大许多。
3.程序风格看着还行,再表扬一下:)

其实现在如果使用现有的密码学上非对称的加密体系的算法,更本是没法制作注册机的。所以现在研究主要不在于判定序列号,而在于防止程序本身被修改= =
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TsaiGreen 2010-3-4 13:35
3
0
2.使用LIS的算法太简单,O(n^2)的DP,哪怕是反汇编也一眼就看完了,建议可以改进成O(nlogn)的LIS算法(有DP和贪心两种)。并且可以考虑把LIS计算过程中的方案也求出来,并用到加密上,就会强大许多。
----------------------这个学习了。----------------

您们搞破解,我来学加密。

/*
  Name: 动态规划用于软件加密初探(2) 
  Copyright: @Green Tsai
  Author: Green Tsai
  Date: 04-03-10 13:09
  Description: 
		1,思路与思想:本程序试图将动态规划算法用于软件加密,主要涉及动态规划中的字符串编辑距离与相似度判定。
		2,本程序中的编辑代价函数与相似度判定函数均可调整来增加加密强度与逆向难度。 
		3,示例姓名:kanxue,序列号:90yxop。
	参考文档:《挑战编程》 Steven S.Skiena著 刘汝佳 译 
*/
#include <cstdlib>
#include <iostream>

using namespace std;

#define MAXLEN 35

#define MATCH	0		// enumerated type symbol for match
#define INSERT 	1		
#define DELETE  2

typedef struct
{
	int cost;		// cost of reaching this cell
	int parent;		// parent cell
}cell;
cell m[MAXLEN+1][MAXLEN+1];		// dynamic programming table

// 代价函数 
int match(char c,char d);
int indel(char c);
// 初始化与目标格 
void row_init(int i);
void column_init(int i); 
void goal_cell(char *s,char *t,int *i,int *j);
// 编辑距离
int string_compare(char *s,char *t);
// 相似度判定 
bool same(char *s,char *t);
 
int main()
{
	bool ok=false;		
	while(ok==false)
	{
		char name[31],serial[31];
		name[0]=serial[0]='!';		
		cout<<"Please input your name:"<<endl;
		cin>>&name[1];
		cout<<"Please input your serial number:"<<endl;
		cin>>&serial[1];		
  	    	
  	    // cout<<strlen(name)<<" "<<strlen(serial)<<endl;
  	    // cout<<string_compare(name,serial)<<endl;
    	if( strlen(name)>=4 && ( strlen(name)==strlen(serial) ) && same(name,serial) && string_compare(name,serial)==5 )
		{	
			ok=true;
			cout<<"Congratulations!"<<endl;
			cout<<endl;
		}
		else
		{
			cout<<"Sorry!"<<endl;
			cout<<endl;
		}  
	}
	
	system("PAUSE");
	return 0;   
	system("PAUSE");
	return 0;
}

int match(char c,char d)
{
	if(c==d)
		return 0;
	else 
		return 1;		
}
int indel(char c)
{
	return 1;
}

void row_init(int i)
{
	m[0][i].cost=i;
	if(i>0) m[0][i].parent=INSERT;
	else m[0][i].parent=-1;
}
void column_init(int i)
{
	m[i][0].cost=i;
	if(i>0) 
		m[i][0].parent=DELETE;
	else 
		m[0][i].parent=-1;
}
void goal_cell(char *s,char *t,int *i,int *j)
{
	*i=strlen(s)-1;
	*j=strlen(t)-1;
}	
int string_compare(char *s,char *t)
{
	int i,j,k;		// counter
	int opt[3];		// cost of the three options
	
	for(i=0;i<MAXLEN;i++)
	{
		row_init(i);
		column_init(i);
	}
	
	for(i=1;i<strlen(s);i++)
	{
		for(j=1;j<strlen(t);j++)
		{
			opt[MATCH]=m[i-1][j-1].cost+match(s[i],t[j]);
			opt[INSERT]=m[i][j-1].cost+indel(t[j]);
			opt[DELETE]=m[i-1][j].cost+indel(s[i]);
			
			m[i][j].cost=opt[MATCH];
			m[i][j].parent=MATCH;
			for(k=INSERT;k<=DELETE;k++)
			{
				if(opt[k]<m[i][j].cost)
				{
					m[i][j].cost=opt[k];
					m[i][j].parent=k;
				}
			}
		}
	}
	goal_cell(s,t,&i,&j);
	return m[i][j].cost;
}
bool same(char *s,char *t)
{
	// 相似度小于50%,返回true 
	int count=0;
	for(int i=1;i<strlen(s);i++)
	{
		if(s[i]==t[i])
			count++;
	}
	if(count<=strlen(s)/2)
		return true;
	else
		return false;
}

上传的附件:
雪    币: 424
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
resty 2 2010-3-4 13:51
4
0
随便看了一下,这个程序嘛:
用户名resty的话,密码随便选一个5位数都行
是用户名越长越麻烦,有的用户名可能还不那么容易产生注册码

顺便路过膜拜本书的翻译者
雪    币: 90
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wangyuchen 2010-3-4 17:37
5
0
谢谢了,谢谢一下先了
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TsaiGreen 2010-3-4 18:10
6
0
这么大的秘密,竟然被你看出来了。。。

早知道我把编辑代价和相似度搞的复杂点了。。。
游客
登录 | 注册 方可回帖
返回