您的位置:首页 > 其它

浅谈利用RSA算法防止非法注册机的制作

2013-01-19 15:54 323 查看
一、RSA简介

RSA公开密钥密码系统是由R.Rivest,A.Shamir,L.Adleman提出的,不仅仅可用于数据的加密,也可用于数字签名,其算法如下:

1、取两个相近的大素数p、q;

2、计算n=p*q,z=(p-1)*(q-1);

3、任取一个与z互素的整数e;

4、计算满足e*d=1 mod z 的整数d;

5、将明文m分成字符块s加密,每个块s小于n。现设明文m小于n,加密后形成密文c。 加密、解密过程如下:

加密:c=m^e mod n

解密:m=c^d mod n

6、(n,e)和(n,d)分别称为“公开密钥”和“秘密密钥”。根据Euler定理可得:

m=c^d mod n=(m^e mod n)^d mod n=m

现举例说明其工作过程:取两个素数p=11,q=13,n=p*q=11*13=143,z=(p-1)*(q-1)=(11-1)*(13-1)=120,再选取与z=120互素的整数e,如e=7,现可计算出满足7*d=1 mod 120的整数d=103,即:7*103=1 mod 120,7*103/120余1,整理如下:

1.
p=11

2.
q=13

3.
n=143

4.
e=7

5.
d=103

6.
(n,e)=(143,7)

7.
(n,d)=(143,103)


以数据加密为例:

甲向乙发送机密数据信息m=85,并已知乙的公钥(n,e)=(143,7),于是可计算出:

1.
c=m^e mod n=85^7 mod 143=123


甲将c发送至乙,乙利用私钥(n,d)=(143,103)对c进行计算:

1.
m=c^d mod n=123^103 mod 143=85


现乙已经得到甲向其要发送的机密数据信息。在这里,甲向乙发送信息,甲所拥有的仅仅是乙的公钥。

以数字签名为例:

乙要向甲发送信息,并要让甲确信此信息是由乙本人所发出的,于是,乙将能代表自己身份的编码值(如:123),利用私钥(n,d)=(143,103)进行计算,并将结果发送给甲:

1.
m=c^d mod n=123^103 mod 143=85


甲接受到乙的数字签名后利用乙的公钥(n,e)=(143,7)进行计算,得出代表乙身份的编码:

1.
c=m^e mod n=85^7 mod 143=123


现甲经过验证已确信信息的发送方为乙。因为只有乙拥有私钥(n,d),来对代表自己身份的编码123进行计算。在不知道乙私钥(n,d)的情况下,任何人都不会算出85这一签名来冒充乙。在这里,乙向甲发送信息并进行签名,甲所拥有的也仅仅是乙的公钥来验证乙的签名。

从上面两个例子中我们可以更好得理解这一结论,即:由(n,e)加密的数据只能用(n,d)解密,反之亦然。

二、在基于序列号保护的共享软件中应用RSA

结合数字签名的实例能更好得理解这一应用:在某一共享软件中,甲想用123为注册名进行软件注册,他现在拥有的仅仅是存在于共享软件程序中的公钥(n,e)=(143,7)。甲现将123为注册名向乙提出注册申请,乙得知此申请并通过此申请后,便利用所拥有的私钥(n,d)对注册名123进行计算:

1.
m=c^d mod n=123^103 mod 143=85


甲得到计算后的结果85(序列号),提供给共享软件的注册程序进行计算:

1.
c=m^e mod n=85^7 mod 143=123

然后注册程序将判断计算结果c是否为123(注册名),以决定注册是否通过。

如果甲随意输入一组序列号利用公钥(n,e)进行计算,那他得到的结果将不是123,注册也就失败了。注意,在这里,共享软件的注册程序比较的是注册名,而不是序列号。如果甲跟踪注册程序得到了他所随意输入的序列号所产生的注册名,将其提供给注册程序,那注册程序也能够通过注册,但他由于没有(n,d),所以他无法用自己的注册名进行软件注册,也就防止了非法注册机的制作。

将RSA应用于此的目的仅仅是防止非法注册机的制作,在以上描述中,n=143,包括以下Demo中的n(HEX)=963251DC5A9C90D9F203A03C363BA411,以现在的计算机处理速度,能很快地将其因式分解得到相应的p,q,再结合暴露在共享软件注册程序中的e,从而计算出d,那么这个共享软件的保护就完全被破解了。解决的方法是要避免n过短,以及结合MD5等加密算法……

三、具体实践

/* RSA Demo 1.0 版

* 版权所有 (C) 2004 赵春生

* 2004.04.25

* http://timw.yeah.net
* http://timw.126.com
* 本程序调用Miracl ver 4.82大数运算库,详见其附带手册。

* P,Q,N,D,E使用RSATool2生成。

*/

1、注册机的关键代码:

01.
void

CKeyGenDlg::OnGen()

02.
{

03.
// TODO: Add your control notification handler code here

04.

05.
/* KeyGen 1.0 版

06.
* 版权所有 (C) 2004 赵春生

07.
* 2004.04.25

08.
*
http://timw.yeah.net

09.
*
http://timw.126.com

10.
* 本程序调用Miracl ver 4.82大数运算库,详见其附带手册。

11.
*/

12.

13.
////////////////////////////////////////////////////////////

14.

15.
//P(HEX)=E34436F5F48A227B

16.
//Q(HEX)=A92FA24467C4E3E3

17.
//N(HEX)=963251DC5A9C90D9F203A03C363BA411

18.
//D(HEX)=56157D29A89D77BF2F669A8F0B123CC9

19.
//E(HEX)=10001

20.
//Keysize(Bits)=128

21.

22.
UpdateData(TRUE);

23.

24.
int

namelen=m_name.GetWindowTextLength ();
//获取Name的长度

25.

26.
//务必满足:Name的长度<=(Keysize/8),使M < N成立。

27.
if

(namelen!=0&&namelen<=16)
//如果不为空且< =128/8则开始计算SN

28.
{

29.
miracl *mip=mirsys(100,0);

30.
mip->IOBASE=16;
//16进制模式

31.

32.
//定义并初始化变量

33.
big m=mirvar(0);
//m 放明文:注册码SN

34.
big c=mirvar(0);
//c 放密文:用户名Name

35.
big n=mirvar(0);
//n 模数

36.
big d=mirvar(0);
//d 私钥

37.
TCHAR

Name[256]={0};

38.
TCHAR

SN[256]={0};

39.

40.
m_name.GetWindowText (Name,namelen+1);
//获取Name

41.
bytes_to_big(namelen,Name,c);
//转换成16进制

42.
cinstr(n,
"963251DC5A9C90D9F203A03C363BA411"
);
//初始化模数n

43.
cinstr(d,
"56157D29A89D77BF2F669A8F0B123CC9"
);
//初始化私钥d

44.
powmod(c,d,n,m);
//计算m=c^d mod n

45.
cotstr(m,SN);
//将m以16进制串写入SN

46.
m_sn.SetWindowText (SN);
//输出16进制SN

47.

48.
//释放内存

49.
mirkill(m);

50.
mirkill(c);

51.
mirkill(n);

52.
mirkill(d);

53.
mirexit();

54.
}

55.
else

56.
m_sn.SetWindowText (
"Error: Invalid registration name."
);

57.

58.
UpdateData(FALSE);

59.
}


2,软件中注册程序的关键代码:

01.
void

CRSAApplicationDlg::OnReg()

02.
{

03.
// TODO: Add your control notification handler code here

04.

05.
/* RSA Application 1.0 版

06.
* 版权所有 (C) 2004 赵春生

07.
* 2004.04.25

08.
*
http://timw.yeah.net

09.
*
http://timw.126.com

10.
* 本程序调用Miracl ver 4.82大数运算库,详见其附带手册。

11.
*/

12.

13.
/////////////////////////////////////////////////////////////

14.

15.
//P(HEX)=E34436F5F48A227B

16.
//Q(HEX)=A92FA24467C4E3E3

17.
//N(HEX)=963251DC5A9C90D9F203A03C363BA411

18.
//D(HEX)=56157D29A89D77BF2F669A8F0B123CC9

19.
//E(HEX)=10001

20.
//Keysize(Bits)=128

21.

22.
UpdateData(TRUE);

23.

24.
miracl *mip=mirsys(100,0);

25.
mip->IOBASE=16;
//16进制模式

26.

27.
//定义并初始化变量

28.
big m=mirvar(0);
//m 放明文:注册码SN

29.
big c=mirvar(0);
//c 放密文:用户名Name

30.
big n=mirvar(0);
//n 模数

31.
big e=mirvar(0);
//e 公钥

32.
TCHAR

Name[256]={0};

33.
TCHAR

SN[256]={0};

34.
TCHAR

temp[256]={0};

35.
int

len=0;

36.
int

i,j;

37.

38.
//获取Name

39.
len=m_name.GetWindowTextLength ();

40.
m_name.GetWindowText (Name,len+1);

41.

42.
//获取SN

43.
len=m_sn.GetWindowTextLength ();

44.
m_sn.GetWindowText (SN,len+1);

45.

46.
//检查SN是否为16进制

47.
for

(i=0,j=0;i< len;i++)

48.
{

49.
if
(
isxdigit
(SN[i])==0)

50.
{

51.
j=1;

52.
break
;

53.
}

54.
}

55.

56.
//如果输入的SN为16进制且长度不为0

57.
if

(j!=1&&len!=0)

58.
{

59.

60.
cinstr(m,SN);
//初始化明文m

61.
cinstr(n,
"963251DC5A9C90D9F203A03C363BA411"
);
//初始化模数n

62.
cinstr(e,
"10001"
);
//初始化公钥e

63.

64.
//当m< n时

65.
if
(compare(m,n)==-1)

66.
{

67.
powmod(m,e,n,c);
//计算c=m^e mod n

68.
big_to_bytes(256,c,temp,FALSE);
//将c转换成数组写入temp

69.

70.
//释放内存

71.
mirkill(m);

72.
mirkill(c);

73.
mirkill(n);

74.
mirkill(e);

75.
mirexit();

76.
}

77.
else

78.
j=1;

79.

80.
}

81.

82.
//对Name、temp, m、n, SN的长度进行检查

83.
if
(lstrcmp(Name,temp)!=0||j==1||len==0)

84.
MessageBox(
"Please check your NAME and SN, then try again."
,
"RSA
Application"
);

85.
else

86.
MessageBox(
"Congratulate!!!"
,
"Registration
complete!"
);

87.

88.
UpdateData(FALSE);

89.
}


编译提示:

1、将 Project-Settings-Settings For(All Configuration)-C/C++中Category 项的 Precompiled Headers设置成:Automatic use of precompiled headers(如图一)。



图一

2、将 ms32.lib 添加到工程中(如图二)。



图二

3、MIRACL是C库。

1.
extern

"C"

2.
{

3.
#include "miracl.h"

4.
#include "mirdef.h"

5.
}

6.

7.
#pragma comment( lib, "ms32.lib" )

转载自  http://www.vckbase.com/index.php/wv/887.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: