实现基于IDEA算法的加密工具.docx
- 文档编号:28013334
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:20
- 大小:25.27KB
实现基于IDEA算法的加密工具.docx
《实现基于IDEA算法的加密工具.docx》由会员分享,可在线阅读,更多相关《实现基于IDEA算法的加密工具.docx(20页珍藏版)》请在冰豆网上搜索。
实现基于IDEA算法的加密工具
实现基于IDEA算法的加密工具
1.IDEA算法的相关背景
1990年XueJiaLai和Massey开发出IDEA加密算法雏形,称为PES,即"建议的加密标准"。
第二年,根据有关专家对这一密码算法的分析结果,设计者对该算法进行了强化并称之为IPES,即"改进的建议加密标准"。
该算法于1992年更名为IDEA,即"国际加密标准"。
IDEA算法的密钥长度为128位,针对64位的数据进行加密或解密操作.设计者尽可能使该算法不受差分密码分析的影响,XueJiaLai已证明IDEA算法在其8轮迭代的第4圈之后便不受差分密码分析的影响了。
假定穷举法攻击有效的话,那么即使设计一种每秒种可以试验10亿个密钥的专用芯片,并将10亿片这样的芯片用于此项工作,仍需1013年才能解决问题;另一方面,若用1024片这样的芯片,有可能在一天内找到密钥,不过人们还无法找到足够的硅原子来制造这样一台机器。
目前,尚无一片公开发表的试图对IDEA进行密码分析的文章。
因此,就现在来看应当说IDEA是非常安全的。
IDEA有大量的弱密钥,这些弱密钥是否会威胁它的安全性还是一个迷。
IDEA密码能够抵抗差分分析和线性分析。
设计者Lai认为IDEA不是一个群,但目前仍未得到证实。
Eurocrypt'97会议上给出了两种新的攻击低圈IDEA的方法,第一种攻击方法可破译大约3·5-圈的IDEA;第二种攻击方法可破译大约3-圈的IDEA。
但从分析结果来看,这两种攻击方法并未对IDEA的安全性构成威胁。
2.IDEA算法概述
IDEA是一个迭代分组密码,分组长度为64比特,密钥长度为128比特。
IDEA密码中使用了以下三种不同的运算:
逐位异或运算;
模216加运算;
模216+1乘运算,0与216对应。
IDEA算法是由8轮迭代和随后的一个输出变换组成。
它将64比特的数据分成4个子块,每个16比特,令这四个子块作为迭代第一轮的输出,全部共8轮迭代。
每轮迭代都是4个子块彼此间以及16比特的子密钥进行异或,模216加运算,模216+1乘运算。
除最后一轮外把每轮迭代输出的四个子块的第二和第三子块互换。
该算法所需要的"混淆"可通过连续使用三个"不相容"的群运算于两个16比特子块来获得,并且该算法所选择使用的MA-(乘加)结构可提供必要的"扩散"。
3.IDEA算法的具体描述
3.1密钥生成
用户输入128位长密钥
Key=k1k2k3…k127k128
IDEA总共进行8轮迭代操作,每轮需要6个子密钥,另外还需要4个额外子密钥,所以总共需要52个子密钥,这个52个子密钥都是从用户输入的128位密钥中扩展出来的.
首先把输入的Key分成8个16位的子密钥,1~6号子密钥供第一轮加密使用,7~8号子密钥供第二轮使用,然后把这个128位密钥循环左移25位,这样Key=k26k27k28…k24k25
把新生成的Key在分成8个16位的子密钥,1~4号子密钥供第二轮加密使用(前面已经提供了两个)5~8号子密钥供第三轮加密使用,到此我们已经得到了16个子密钥,如此继续,当循环左移了5次之后已经生成了48个子密钥,还有四个额外的子密钥需要生成,再次把Key循环左移25位,选取划分出来的8个16位子密钥的前4个作为那4个额外的加密密钥.供加密使用的52个子密钥生成完毕.
K[0]
K[1]
K[2]
K[3]
K[4]
K[5]
…
K[48]
K[49]
K[50]
K[51]
第一轮
…
额外密钥
3.2加密明文
64-位数据分组被分成4个16-位子分组:
D0,D1,D2,D3。
这4个子分组成为算法的第一轮的输入,总共有8轮。
在第i轮中,假定输入的为:
明文(4组):
D0,D1,D2,D3
密钥(6组)K1,K2,K3,K4,K5,K6
执行的顺序如下:
D0和第一个子密钥(K1)模216+1乘。
D1和第二个子密钥(K2)模216加。
D2和第三个子密钥(K3)模216加。
D4和第四个子密钥(K4)模216+1乘。
第
(1)步和第(3)步的结果相异或。
将第
(2)步和第(4)步的结果相异或。
将第(5)步的结果与第五个子密钥(K5)模216+1乘。
将第(6)步和第(7)步的结果模216加。
将第(8)步的结果与第六个子密钥(K6)模216+1乘。
将第(7)步和第(9)步的结果模216加。
将第
(1)步和第(9)步的结果相异或。
将第(3)步和第(9)步的结果相异或。
将第
(2)步和第(10)步的结果相异或。
将第(4)步和第(10)步的结果相异或。
将第(11)、(12)、(13)和(14)步的结果形成的4个子分组D0,D1,D2,D3作为输出,然后将中间两个分组(D1,D2)交换(最后一轮除外)后,作为为下一轮的输入。
经过8轮运算之后,有一个最终的输出D0,D1,D2,D3,对这4个输出子分组进行如下操作:
(1)D0和第一个额外子密钥模216+1乘。
(2)D1和第二个额外子密钥模216加。
(3)D2和第三个额外子密钥模216加。
(4)D3和第四个额外子密钥模216+1乘。
最后,这4个子分组重新连接到一起产生密文。
3.3.密文解密
介绍IDEA加密算法的资料本就不多而且对于解密过程往往一笔带过,笔者在编程实现IDEA算法时为此大伤脑筋,好在这块骨头总算被啃下了.下文笔者将结合实现代码介绍一下解密过程,如果读者想亲自动手实现IDEA算法,笔者的”痛苦经验”是可以让你少走些弯路的.
解密操作和加密的步骤基本相同,但是在求密钥时有所区别.
首先从用户输入的128位密钥扩展出52个子密钥,存放在ULONG16Key[52]数组中,然后对这个52个子密钥进行换位操作,
新位置:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
原位置:
48
49
50
51
46
47
42
44
43
45
40
41
36
38
新位置:
14
15
16
17
18
19
20
21
22
23
24
25
26
27
原位置:
37
39
34
35
30
32
31
33
28
29
24
26
25
27
新位置:
28
29
30
31
32
33
34
35
36
37
38
39
40
41
原位置:
22
23
18
20
19
21
16
17
12
14
13
15
10
11
新位置:
42
43
44
45
46
47
48
49
50
51
原位置:
6
8
7
9
4
5
0
1
2
3
表中的原位置行的值代表该子密钥在原密钥数组中的位置,比如新密钥数组中的第0号子密钥为原来子密钥组中的第48号子密钥,对子密钥数组换位后,就需要对某些子密钥进行模216+1的乘法逆或模216加法逆的替换,详情见下表(位置是针对换位后的子密钥组)请看下一页
进行加法逆替换的子密钥的位置:
1
2
7
8
13
14
19
20
25
26
31
32
37
38
43
44
49
50
进行乘法逆替换的子密钥的位置:
0
3
6
9
12
15
18
21
24
27
30
33
36
39
42
45
48
51
需要变化的子密钥总共18+18=36个,另外的52–36=16个子密钥不变化.
下面介绍有关x逆元的计算方法.
X模216加法逆比较简单:
x-1=65536–x;
X模216+1乘法法逆和X的关系如下:
(X*X-1)%65537=1
求解X-1需要一定的计算量,具体的算法实现代码如下:
#defineLOW16(x)((x)&0xffff)
ULONG16mulInv(ULONG16x)
{
ULONG16t0,t1;
ULONG16q,y;
if(x<=1)
{
returnx;
}
t1=0x10001L/x;
y=0x10001L%x;
if(y==1)
{
returnLOW16(1-t1);
}
t0=1;
do
{
q=x/y;
x%=y;
t0+=q*t1;
if(x==1)
{
returnt0;
}
q=y/x;
y%=x;
t1+=q*t0;
}while(y!
=1);
returnLOW16(1-t1);
}
3.4注意事项
由于在IDEA中采用了乘法运算,这就要考虑到两个乘数是否为0的情况,如果两个乘数都为0,那么乘法运算结果为0,如果仅有一个乘数为0,那么用65536替换那个为0的乘数,取乘法运算结果的低16位作为输出结果.
INT32MUL(ULONG16a,ULONG16b)/*(a*b)*/
{
ULONG32p;
if(a==0&&b==0)
{
p=0;
}
elseif(a==0)
{
p=65536*(ULONG32)b;
}
elseif(b==0)
{
p=65536*(ULONG32)a;
}
else
{
p=(ULONG32)a*(ULONG32)b;
}
return(ULONG16)(p%65537);
}
3.5算法实现代码
/*此处略去信息说明和头文件*/
#include"idea.h"
#defineNULL((void*)0)
typedefintINT32;
typedefcharINT8;
typedefunsignedcharULONG8;
typedefunsignedshortULONG16;
typedefunsignedlongULONG32;
#defineSUCCESS0
#defineFAIL-1
#defineLOW16(x)((x)&0xffff)
#define_USEDFINDTABLE_1/*是否采用查表实现*/
/*解密时密钥的换位表*/
//ULONG16outkey[52]={0};
staticULONG8wz_spkey[52]={
48,49,50,51,46,47,
42,44,43,45,40,41,/*解密密钥配置,2,3位要交换:
44<->43*/
36,38,37,39,34,35,/*解密密钥配置,2,3位要交换:
38<->37*/
30,32,31,33,28,29,/*解密密钥配置,2,3位要交换:
32<->31*/
24,26,25,27,22,23,/*解密密钥配置,2,3位要交换:
26<->25*/
18,20,19,21,16,17,/*解密密钥配置,2,3位要交换:
20<->19*/
12,14,13,15,10,11,/*解密密钥配置,2,3位要交换:
14<->13*/
6,8,7,9,4,5,/*解密密钥配置,2,3位要交换:
8<->7*/
0,1,2,3
};
staticULONG8wz_spmulrevr[18]={/*变乘法逆的位*/
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51
};
staticULONG8wz_spaddrever[18]={/*变加法逆的位*/
1,2,7,8,13,14,19,20,25,26,31,32,37,38,43,44,49,50
};
INT32mulInv(ULONG16x);/*取x的(%0x10001L)乘法逆*/
INT32handle_data(ULONG16*data,/*待加密的64位数据首地址*/
ULONG16*key/*6组本轮使用的16位长的密钥首地址*/
);
INT32idea_makekey(ULONG32*inkey,/*用户输入的128位密钥首地址*/
ULONG16*outkey/*生成的52组16位密钥的首地址*/
);
INT32key_leftmove(ULONG32*inkey);
INT32key_decryExp(ULONG16*outkey);/*解密密钥的变逆处理*/
INT32MUL(ULONG16a,ULONG16b);/*(a*b)*/
INT32idea_dec(ULONG16*data,/*待解密的64位数据首地址*/
ULONG16*outkey
)
{
ULONG32i;
ULONG16tmp;
if(NULL==data||NULL==outkey)
{
returnFAIL;
}
for(i=0;i<48;i+=6)/*8轮*/
{
handle_data(data,&outkey);
/*交换中间两个*/
tmp=data[1];
data[1]=data[2];
data[2]=tmp;
}
tmp=data[1];/*最后一轮不交换*/
data[1]=data[2];
data[2]=tmp;
data[0]=MUL(data[0],outkey[48]);
data[1]+=outkey[49];
data[2]+=outkey[50];
data[3]=MUL(data[3],outkey[51]);
returnSUCCESS;
}
INT32idea_enc(ULONG16*data,/*待加密的64位数据首地址*/
ULONG16*outkey
)
{
ULONG32i;
ULONG16tmp;
if(NULL==data||NULL==outkey)
{
returnFAIL;
}
for(i=0;i<48;i+=6)/*8轮*/
{
handle_data(data,&outkey);
/*交换中间两个*/
tmp=data[1];
data[1]=data[2];
data[2]=tmp;
}
tmp=data[1];/*最后一轮不交换*/
data[1]=data[2];
data[2]=tmp;
data[0]=MUL(data[0],outkey[48]);
data[1]+=outkey[49];
data[2]+=outkey[50];
data[3]=MUL(data[3],outkey[51]);
returnSUCCESS;
}
INT32handle_data(ULONG16*data,/*待加密的64位数据首地址*/
ULONG16*key/*6组本轮使用的16位长的密钥首地址*/
)
{
ULONG16*D1,*D2,*D3,*D4;
ULONG16D57;/*提供给第5,7步用的暂存数据的*/
ULONG16D68;/*提供给第6,8,9,10步用的暂存数据的*/
D1=&data[0];
D2=&data[1];
D3=&data[2];
D4=&data[3];
/*start*/
*D1=MUL(*D1,key[0]);/*第1步*/
*D2+=key[1];/*第2步*/
*D3+=key[2];/*第3步*/
*D4=MUL(*D4,key[3]);/*第4步*/
D57=*D1^*D3;/*第5步*/
D68=*D2^*D4;/*第6步*/
D57=MUL(D57,key[4]);/*第7步*/
D68+=D57;/*第8步*/
D68=MUL(D68,key[5]);/*第9步*/
*D1^=D68;/*第11步*/
*D3^=D68;/*第12步*/
D68+=D57;/*第10步*/
*D2^=D68;/*第13步*/
*D4^=D68;/*第14步*/
returnSUCCESS;
}
INT32idea_makekey(ULONG32*inkey,/*用户输入的128位密钥首地址*/
ULONG16*outkey/*生成的52组16位密钥的首地址*/
)
{
ULONG32i,j,k;
ULONG16*Pkey=(ULONG16*)inkey;
for(i=0;i<6;i++)
{
k=i<<3;
for(j=0;j<8;j++)/*生成8组密钥*/
{
outkey[k+j]=Pkey[j];
}
key_leftmove(inkey);/*128位密钥左环移25位*/
}
for(i=0;i<4;i++)
{
outkey[48+i]=Pkey;
}
returnSUCCESS;
}
INT32key_leftmove(ULONG32*inkey)/*密钥左环移25位*/
{
ULONG32itmpfirst=0,itmp=0;
ULONG32i;
inkey[0]=(inkey[0]<<25)|(inkey[0]>>7);
/*取低25位,因为前面已经做了环移,原始的低7位已经移到了高位,保存*/
itmpfirst=inkey[0]&0x1ffffff;
inkey[0]&=0xfe000000;/*低25位清0*/
for(i=1;i<4;i++)
{
inkey=(inkey<<25)|(inkey>>7);
itmp=inkey&0x1ffffff;
inkey|=itmp;
inkey&=0xfe000000;/*低25位清0*/
}
inkey|=itmpfirst;/*把最高25位移到最低25位*/
returnSUCCESS;
}
INT32key_decryExp(ULONG16*outkey)/*解密密钥的变逆处理*/
{
/*我习惯用查表的方法实现换位,当然也可以采用一些编程技巧直接实现*/
#if_USEDFINDTABLE_/*用查表法*/
ULONG16tmpkey[52]={0};
ULONG32i;
for(i=0;i<52;i++)
{
tmpkey=outkey[wz_spkey];/*换位*/
}
for(i=0;i<52;i++)
{
outkey=tmpkey;
}
for(i=0;i<18;i++)
{
outkey[wz_spaddrever]=65536-outkey[wz_spaddrever];/*替换成加法逆*/
}
for(i=0;i<18;i++)
{
outkey[wz_spmulrevr]=mulInv(outkey[wz_spmulrevr]);/*替换成乘法逆*/
}
#else
ULONG16K1,K2,K3,K4,i;
ULONG16tmpkey[52]={0};
ULONG16*pin=outkey;
ULONG16*p=tmpkey+52;/*从后往前*/
K1=mulInv(*pin);
K2=65536-*++pin;
K3=65536-*++pin;
K4=mulInv(*++pin);
pin++;
*--p=K4;
*--p=K3;
*--p=K2;
*--p=K1;
for(i=0;i<7;i++)
{
K1=*pin++;/*不变的两个*/
K2=*pin++;
*--p=K2;
*--p=K1;
K1=mulInv(*pin);
K2=65536-*++pin;
K3=65536-*++pin;
K4=mulInv(*++pin);
pin++;
*--p=K4;
*--p=K2;/*交换*/
*--p=K3;
*--p=K1;
}
K1=*pin++;/*最后一组不交换*/
K2=*pin++;
*--p=K2;
*--p=K1;
K1=mulInv(*pin);
K2=65536-*++pin;
K3=65536-*++pin;
K4=mulInv(*++pin);
*--p=K4;
*--p=K3;
*--p=K2;
*--p=K1;
for(i=0;i<52;i++)
{
outkey=tmpkey;
}
#endif
returnSUCCESS;
}
DllExportINT32idea_MakeEncKey(ULONG16*key,ULONG16*outkey)
{
if(NULL==outkey||NULL==key)
{
returnFAIL;
}
idea_makekey((ULONG32*)key,outkey);
returnSUCCESS;
}
INT32i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实现 基于 IDEA 算法 加密 工具