IDEA加密算法使用长度为128位的密钥,对64位的数据进行加密或解密操作,算法只使用了模(216+1)乘法、模216加法和按住异或运算,被广泛运用在各种领域,那么我们今天就来介绍一下用C#.NET是怎么实现的。

一、IDEA加密算法简介

IDEA属于数据块加密算法类,在加密之前.IDEA算法要求将128位的密钥扩展为52个16位的加密密钥EK(Encrypuon- Key),然后由EK计算出52个16位的解密密钥DK(DecryptionKey)。

IDEA加密算法具体步骤如图1所示,由8个相似圈(Round)和一个输出变换(OutputTransformation)组成的迭代算法。首先64位需要加密或解密的数据分组被分成4个16位子分组:T1,12,T3.T4.这4个子分组成为算法的第一轮的输入,使用三种函数进行计算:

C#.NET怎么实现IDEA加密算法

①“田”表示模216加法.在加法计算时,计算输入的类型时和输出类型都要求是无符号短整型(16位正整数),加法结果值可能超过了范围,可以使用强制类型转换,转换结果自动实现模216运算。

②“0”表示模(216 +1)乘法,方法代码如下:

Ulnt16 multi( Ulnt16 a,Ulnt16 b){

Uint32 temp;

if (a- =0&&b= =O}temp =0;}

elseif(8==0){ temp =65536 *6;}

else if(b==0){ temp =65536.a;)

else temp=a,b;

temp=a*b;

a=(Ulnt16)( temp%65537);

retuma;}

③“0"表示和按位异或运算,c#有“⌒”运算符,可以直接实现按位异或运算。

总共经过8轮运算后,在输出变换中4个子分组与最后4个子密钥进行运算,产生的4个子分组重新连接到一起产生密文。解密过程基本上一样,只是密钥不一样。

实际在C#.NET中使用IDEA加密算法,密钥一般是不变的,因此可将扩展后的加密密钥EK(52组)和解密密钥DK(52组)事先计算出来,存储在程序的数组变量中,这样就可以加快加密解密的速度。

二、IDEA加密密钥EK和解密密钥DK的获得

IDEA的密钥是128位,在选择用于IDEA的密钥时,应该排除那些称为“弱密钥”的密钥,作者通过使用不断重复出现的128位原始密钥,通过特别选定的密文可以测试和观察出密钥所含的线性因子,而且在8轮的迭代中,线性因子不断地扩展进入密钥,最后可得出其中的55位密钥的值,具体为第26-40、72-83和99 -12,这也就是说弱密钥数有251个,但密钥的总数是2128个,仍有277个密钥可供选择。

加密密钥EK的生成是从128位密钥扩展出52个加密子密钥,每个子密钥16位,过程如下:

①由128位的密钥生成EK的前8个子密钥;

②前8个子密钥循环左移25位,得到EK的下8个子密钥,将这个过程循环7次;

③在第7次循环时,只需取前4个子密钥。

解密密钥EK的获得方法如下:

①对这个加密密钥EK的52个子密钥进行换位操作,原来的48、49、50、51、46、47、42、44、43、45、40、41、36、38、37、39、34、35、30、32、31、33、28、29、24、26、25、27、22、23、18、20、19、21、16、17、12、14、13、15、10、ll、6、8、7、9、4、5、O、1、2、3位置分别调换成新的O—5l位置;

②换位后,对位置是l、2、7、8、13、14、19、20、25、26、31、32、37、38、43 .44、49、50的子密钥进行模216的加法逆运算,运算公式是A =65536 -x,A是结果;

③对位置是O、3、6、9、12、15、18 .21、24、27、30、33、36、39.42 \45、48.51的子密钥进行模216 +1的乘法逆运算,运算公式是(x* A) t7065537=1,A乘法逆运算是结果。0和1的乘法逆是自己,其它可以通过穷举算法获得。

三、IDEA加密算法加密解密过程在C#中的详细实现

程序假设加密密钥DK(52个子密钥)和解密密钥EK(52个子密钥)已经存在数组EK[52]和DK[52]中,64位加密或解密数据存在数组data[4]中,代码为:

Ulnd6 data[4];//定义64位加密或解密数据存储空间,

Ulnd6 code EK[52]=l……};//加密密钥EK

Ulnt16 code DK[52]={……l;//解密密钥DK

加密过程的代码如下:

shorti;

Ulnt16 tmp,ryn,DT2;

for(i =0;i<48;i+;6){//共8轮

data[0]=multi( data[0] ,EK[i+0]);

data[l]=(Ulnt16)(EK[i+l] +data[l]);

data[2] = ( Ulnd6) (EK[i+2] +data[2l);

data[3] = multi( data[3] ,EK[i+3l) ;

DTI = data[0] ^data[2] ;DT2 = data[l] ^data[3];

DTl = multi( IYIl,EK[4 +i)) ;DT2 = Ulnd6( DTI + DT2) ;

DT2=multi( DT2,EK[5 +i]);IY12=Ulnt16( DTI+DT2);

data[0]^= DT2; data[2]^= DT2;

data[1]“=DT2; data[3]“=DT2;

tmp=data[1];data[ll=data[2];data[2]=tmp;l

tmp=data[l];data[l]=data[2];

data[2]=tmp;//第8轮不交换

data[0]=multi( data[0] ,EK[48]);

data[l)=(Ulnt16) (EK[49] +data[ll);

data[2]=(UInt16)( EK[ 50]+data[2]);

data[3]=multi( data[3],EK[51J);

输出的data[]数组即加密后的数据,解密操作和加密的步骤基本相同,其代码基本一样,只是密钥有所区别,解密时子密钥使用解密密钥数组DK[]。

小知识之C#.net

C#是一个语言,.net是一个平台,上面支持用C#或者VB .Net写代码。
另外,C#不但可以开发基于.net的应用程序,也可以开发基于WinForm的程序,这就是区别。