idea密码算法有哪些的唯一解码量

Error系统找不到指定的文件。常见密码算法总结--(1)分组对称密码
标 题:常见密码算法总结--(1)分组对称密码
作 者:njzjh
时 间:<font color="#10-05-27 23:22:33 链 接:
常见密码算法总结--(1)分组对称密码
/showthread.php?t=113921
NJZhuJinhua@csdn&May.27,&2010
http://blog.csdn.net/njzhujinhua
转载请注明出处。
《常见密码算法总结--(2)分组密码加密模式》见
《常见密码算法总结--(3)加密模式的openssl代码分析》见
(一)分组对称密码
(二)非对称密码
(三)杂凑Hash函数
(一)分组对称密码
第一个得到广泛应用的密码算法,属于对称,分组密码系列,输入明文64位,密钥56位,密文64位。DES密钥太短,已经远远不能适应保密需要。另外DES设计为用硬件实现,软件实现时效率很低,3DES更加低效。
属于对称,分组密码,明文64位,密钥128位,密文64位。由来学嘉和James&Massey提出,是一种专利算法,在欧洲使用较广。
是Ron&Rivest为RSA设计的密码算法,
RC4:变长密钥,Rivest在1987年设计
RC5:分组长,密钥长,及轮数均可变的对称,分组密码。Rivest在1994年设计。
NIST发起高级加密标准的评选,要求实现更快,安全性至少要达到3DES水平,应该使用128位分组,支持256位密钥,128与192位密钥也必须支持。
进入最后一轮的有Rijndael,&Serpent,&Twofish,&RC6&and&MARS。其中Rijndael最后胜出,成为了AES。Rijndael将替换DES-3DES。
Serpent达到了Rijndael的安全性但是运行较慢,排在第二位;运行最快的是RC6但是安全性稍逊于Rijndael。所有参选的AES其密钥为128-256位,Twofish在密钥小于256时暂时超过Rijndael,排在第三。Blowfish的安全性也很高,未见对其的有效攻击,但因其分组只有64位,在加密大量数据时的低效而没有入选AES的短名单。
Rijndael是分组迭代密码,分组长可谓128,192,256;密钥长可谓128,192,256。为满足AES,Rijndael的分组长主要使用128位。Rijndael的轮数为10,12,14轮。
继美国2000年发布AES后,2003年2月欧洲最新一代的安全标准NESSIE(New&European&Schemes&for&Signatures、Integrity&and&Encryption)发布,其中的两个128位分组密码算法是camellia和AES。
camellia算法支持128位分组,密钥可以为128,192,256位,接口与AES一致。对此算法尚无了解,待后续补充。
标 题:常见密码算法总结--(2)分组密码加密模式
作 者:njzjh
时 间:<font color="#10-05-30 23:03:46 链 接:
《常见密码算法总结--(1)分组对称密码》见
《常见密码算法总结--(3)加密模式的openssl代码分析》见
NJZhuJinhua@csdn&May.30,&2010
转载请注明出处。
(二)分组密码加密模式
本来计划第二节写非对称密码的,但发在pediy看雪后读者说第一写的太粗,特决定把openssl的实现一起拉进来结合其代码分析学习。
本节讲分组密码的工作模式。
为了对长度超过密码算法分组大小的明文进行加密,设计到分组密码的工作模式的问题,简单说就是分组块进行加密时的链接关系。也可以理解为密码算法如DES,AES等解决的是一个分组长度的明文加密成密文的过程,而对于任意长度的明文的加密过程则以加密算法为基础,并在某种工作模式下来完成加密过程。因而单独说此数据采用什么算法加密的是没意义的,同样是aes加密,模式不一样时,密文不一样。有了密文,有了密钥,不知道加密模式的话一样无法解密。
分组密码的工作模式主要有
(1)电子密码本模式ECB
(2)密码分组链接模式CBC
(3)密码反馈模式CFB
(4)输出反馈模式OFB
(5)计数器模式CTR
(6)密文挪用模式CTS
(1)电子密码本模式ECB
将明文的各个分组独立的使用相同的密钥进行加密,这种方式加密时各分组的加密独立进行互不干涉,因而可并行进行。同样因为各分组独立加密的缘故,相同的明文分组加密之后具有相同的密文。该模式容易暴露明文分组的统计规律和结构特征。不能防范替换攻击。
其实照实现来看,ECB的过程只是把明文进行分组,然后分别加密,最后串在一起的过程。当消息长度超过一个分组时,不建议使用该模式。在每个分组中增加随机位(如128位分组中96位为有效明文,32位的随机数)则可稍微提高其安全性,但这样无疑造成了加密过程中数据的扩张。
(2)密码分组链接模式CBC
该模式将当前分组的明文与前一个分组的密文的异或作为加密算法的输入。加密后的密文继续参与下一个分组的加密过程。在第一个分组的加密时需要一个初始向量IV,起到虚拟的第0个分组的密文的作用。
记c_0=IV的话
第i个分组m_i的加密过程可以表示为c_i=E_k(m_i&\oplus&c_{i-1})
(这里及以后的下标等表示采用TEX语法。)
解密过程也是从第一个分组开始,第i个密文分组c_i的解密为m_i=E_k^{-1}(c_i)&\oplus&c_{i-1}。
在CBC模式下,相同的明文经相同密钥及IV下,将产生相同的密文。改变任一个,密文则不同。这一性质说明CBC模式可以用于消息认证,即用来产生消息认证吗MAC。将MAC附着在明文分组的后面,使接收消息的人可以确认消息的来源正确且中途没有被篡改过。
CBC模式的自同步:由于CBC链接属性,使密文c_i依赖于m_i以及c_{i-1},而c_{i-1}又依赖于i-1明文及i-2的密文,因而c_i相当于依赖于m_i及前面所有的明文分组。因而过程中明文一位的改变影响后面所有密文的值。而解密过程中密文中一位的改变仅影响本分组以及下一个分组的解密,对于再下一个密文分组的解密则无影响。CBC模式是自同步或密文自动密钥,对于位错误或丢失整个分组情况下,很快能恢复。但是,对于位丢失这样的分组边界错位则没办法了。
(3)密码反馈模式CFB
CFB模式时产生一个密钥流并与分组中的一部分尽心运算。可以将一个大分组分成很多小部分,如128位分组分成16份,每份8位进行一次运算,可以即时输出8位的密文。甚至可以分成128份,每次一位的输出,但如此依赖循环次数大大增加,效率极低。
加密过程可以描述为
第i部分的密文为c_i=m_i&\oplus&Z_i其中
Z_i=E_k(c_{i-1})。
CFB模式的加密过程与解密过程完全相同,不能用于公钥算法
(4)输出反馈模式OFB
与CFB相同的是都是利用分组密码产生流密码的密钥流,不同的是密钥流与密文无关了,而仅与IV及密钥K有关。
加密过程可以描述为
第i部分的密文为c_i=m_i&\oplus&Z_i其中
Z_i=E_k(Z_{i-1})。
解密时直接生成Z=Z_1|Z_2|Z_3|Z_4|Z_5...;
然后M=m_1|m_2|m_3...=c_1&\oplus&Z_1&|&c_2&\oplus&Z_2&|...
(5)计数器模式CTR
计数器模式类似于OFB,差别是构造密钥流的方式不一致:计数器模式的密钥流是通过使用密钥K加密系列计数器产生的。
选择一个计数器ctr,是一个长度与明文分组长度相同的比特串,首先构造一系列长度为分组长度的比特串,记为:
Z=Z_1|Z_2|Z_3|Z_4|Z_5...
Z_i=(ctr+i-1)mod&2^n&&这里n为分组长。
加密过程表示为c_i=m_i&\oplus&Z_i
解密过程表示为m_i=c_i&\oplus&Z_i
(6)CTS密文挪用模式
用于处理任意长度明文数据,并产生相同长度的密文数据。除最后两个明文分组外,对前面的所有块CTS模式与CBC模式效果一样。
标 题:常见密码算法总结--(3)加密模式的openssl代码分析
作 者:njzjh
时 间:<font color="#10-05-30 23:16:52 链 接:
《常见密码算法总结--(1)分组对称密码》见
《常见密码算法总结--(2)分组密码加密模式》见
NJZhuJinhua@csdn&May.30,&2010
转载请注明出处。
(三)加密模式的openssl代码分析
openssl(本文所用openssl代码为1.0.0版本,发布。http://www.openssl.org&本文所用的内容最近几年应该未有更新,因而版本似乎也没多少关系)代码中crypto\modes目录下提供了cbc128,cfb128,ctr128,cts128,ofb128模式的实现。modes.h提供接口声明,其余诸文件分别提供了各种模式。
typedef&void&(*block128_f)(const&unsigned&char&in[16],
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&out[16],
&&&&&&&&&&&&&&&&&&&&&&&&&&&const&void&*key);
typedef&void&(*cbc128_f)(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&int&enc);
//cbc128的加密与解密
void&CRYPTO_cbc128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block);
void&CRYPTO_cbc128_decrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block);
//ctr128的加密与解密
void&CRYPTO_ctr128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&unsigned&char&ecount_buf[16],
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&int&*num,&block128_f&block);
//ofb128的加密与解密
void&CRYPTO_ofb128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&int&*num,
&&&&&&&&&&&&&&&&&&&&&&&&&&&block128_f&block);
//cfb128的加密与解密
void&CRYPTO_cfb128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&int&*num,
&&&&&&&&&&&&&&&&&&&&&&&&&&&int&enc,&block128_f&block);
void&CRYPTO_cfb128_8_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&length,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&int&*num,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int&enc,&block128_f&block);
void&CRYPTO_cfb128_1_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&bits,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&int&*num,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int&enc,&block128_f&block);
//cts128模式
size_t&CRYPTO_cts128_encrypt_block(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block);
size_t&CRYPTO_cts128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&cbc128_f&cbc);
size_t&CRYPTO_cts128_decrypt_block(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block);
size_t&CRYPTO_cts128_decrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&ivec[16],&cbc128_f&cbc);
我们按照cbc,cfb,ofb的顺序进行。
(1)CRYPTO_cbc128_encrypt&CRYPTO_cbc128_decrypt
该函数在libeay32的实现中被
seed_cbc.c(SEED_cbc_encrypt())
cts128.c(CRYPTO_cts128_encrypt_block())
cmll_cbc.c(Camellia_cbc_encrypt())
aes_cbc.c(AES_cbc_encrypt())
例如aes_cbc.c中:
void&AES_cbc_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&size_t&len,&const&AES_KEY&*key,
&&&&&&&&&unsigned&char&*ivec,&const&int&enc)&{
&&if&(enc)
&&&&CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
&&&&CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
AES的加解密公用一个函数,具体是加密还是解密通过参数enc指示。AES_cbc_encrypt通过将参数原封不动粗韩给CRYPTO_cbc128_encrypt或者CRYPTO_cbc128_encrypt完成加解密。最后一个回调函数AES_encrypt和AES_descrypt即使用该模式的加密算法,用于加密一个分组。
其他模式也基本同这例子,后面的模式不再详细说明其怎么跟加密算法的结合。
void&CRYPTO_cbc128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block)
&&&&size_t&n;
&&&&const&unsigned&char&*iv&=&
//确保明文,密文,密钥及初始向量指针的有效性
&&&&assert(in&&&&out&&&&key&&&&ivec);
#if&!defined(OPENSSL_SMALL_FOOTPRINT)
&&&&if&(STRICT_ALIGNMENT&&&
&&&&&&&&((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t)&!=&0)&
//cpu对其,但in&out及ivec中有一个不是sizeof(size_t)字节对齐的,如地址为0x,sizeof(size_t)==4情况下
&&&&&&&&while&(len&=16)&
&&&&&&&&&&&&for(n=0;&n&16;&++n)
&&&&&&&&&&&&&&&&out[n]&=&in[n]&^&iv[n];【A】
第一次循环时iv为入参给的ivec,之后的循环已经在【C】处被设为新产生的密文了
&&&&&&&&&&&&(*block)(out,&out,&key);【B】
调用具体的回调函数,第一个参数为【A】处算出的明文分组与上一个密文分组的异或分组。第二个参数out为出参,意思是加密之后的值还写到out所在的内存。key为提供的密钥。
&&&&&&&&&&&&iv&=&【C】
更新密文分组,用于下一分组的明文进行异或。
&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&out&+=&16;
移动指针等,准备处理下一分组。当剩余的len小于16时,或压根输入就小于16时进行后面【D】的流程
这个与上一个目的一样,不过对已经对齐的情形进行了优化,一次处理了sizeof(size_t)个字节的异或运算而已。
&&&&&&&&while&(len&=16)&
&&&&&&&&&&&&for(n=0;&n&16;&n+=sizeof(size_t))
&&&&&&&&&&&&&&&&*(size_t*)(out+n)&=
&&&&&&&&&&&&&&&&*(size_t*)(in+n)&^&*(size_t*)(iv+n);
&&&&&&&&&&&&(*block)(out,&out,&key);
&&&&&&&&&&&&iv&=&
&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&out&+=&16;
&&&&while&(len)&【D】
如果定义了OPENSSL_SMALL_FOOTPRINT&则上述并未执行,len仍是入参的len。否则这里的len经上面处理后应该是小于16的了。下面处理总体来说逻辑跟上面差不多,多了len&16的情形的处理。
&&&&&&&&for(n=0;&n&16&&&&n&&++n)
&&&&&&&&&&&&out[n]&=&in[n]&^&iv[n];【E】
如果实际剩余长度len小于16则对len字节进行异或运算,否则对分组长16字节进行运算。
&&&&&&&&for(;&n&16;&++n)
&&&&&&&&&&&&out[n]&=&iv[n];【F】
如果上述len小于16的情形,需要执行【F】,及最后一个分组的明文的最后字节用上一个分组的密文对应字节填充(在明文总长度就小于16时则是用初始向量填充了)
&&&&&&&&(*block)(out,&out,&key);
对分组加密
&&&&&&&&iv&=&
&&&&&&&&if&(len&=16)&
&&&&&&&&len&-=&16;
&&&&&&&&in&&+=&16;
&&&&&&&&out&+=&16;
&&&&memcpy(ivec,iv,16);
//cbc128模式的解密函数
void&CRYPTO_cbc128_decrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&size_t&len,&const&void&*key,
&&&&&&&&&&&&unsigned&char&ivec[16],&block128_f&block)
&&&&size_t&n;
&&&&union&{&size_t&&unsigned&char&c[16];&}&
&&&&assert(in&&&&out&&&&key&&&&ivec);
#if&!defined(OPENSSL_SMALL_FOOTPRINT)
&&&&if&(in&!=&out)&解密后的明文是否放在密文的内存中
&&&&&&&&const&unsigned&char&*iv&=&
&&&&&&&&if&(STRICT_ALIGNMENT&&&
&&&&&&&&&&&&((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t)&!=&0)&
&&&&&&&&&&&&while&(len&=16)&
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&(*block)(in,&out,&key);解密一个分组
&&&&&&&&&&&&&&&&for(n=0;&n&16;&++n)&&到这里out为该分组对应的明文分组与前一个密文分组的异或。
&&&&&&&&&&&&&&&&&&&&out[n]&^=&iv[n];
&&&&&&&&&&&&&&&&iv&=&到这里后out为明文分组了
&&&&&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&&&&&out&+=&16;
&&&&&&&&&&&&}
&&&&&&&&else&
&&&&&&&&&&&&while&(len&=16)&
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&(*block)(in,&out,&key);与上同理
&&&&&&&&&&&&&&&&for(n=0;&n&16;&n+=sizeof(size_t))
&&&&&&&&&&&&&&&&&&&&*(size_t&*)(out+n)&^=&*(size_t&*)(iv+n);
&&&&&&&&&&&&&&&&iv&=&
&&&&&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&&&&&out&+=&16;
&&&&&&&&&&&&}
&&&&&&&&memcpy(ivec,iv,16);
&&如果解密后的明文放到原密文的地方,则执行此部分。除了使用临时变量tmp中转一下外与上一样,略
&&&&&&&&if&(STRICT_ALIGNMENT&&&
&&&&&&&&&&&&((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t)&!=&0)&
&&&&&&&&&&&&unsigned&char&c;
&&&&&&&&&&&&while&(len&=16)&
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&(*block)(in,&tmp.c,&key);
&&&&&&&&&&&&&&&&for(n=0;&n&16;&++n)&
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&c&=&in[n];
&&&&&&&&&&&&&&&&&&&&out[n]&=&tmp.c[n]&^&ivec[n];
&&&&&&&&&&&&&&&&&&&&ivec[n]&=&c;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&&&&&out&+=&16;
&&&&&&&&&&&&}
&&&&&&&&else&
//字节对齐时的优化操作
&&&&&&&&&&&&size_t&c;
&&&&&&&&&&&&while&(len&=16)&{
&&&&&&&&&&&&&&&&(*block)(in,&tmp.c,&key);
&&&&&&&&&&&&&&&&for(n=0;&n&16;&n+=sizeof(size_t))&{
&&&&&&&&&&&&&&&&&&&&c&=&*(size_t&*)(in+n);
&&&&&&&&&&&&&&&&&&&&*(size_t&*)(out+n)&=
&&&&&&&&&&&&&&&&&&&&*(size_t&*)(tmp.c+n)&^&*(size_t&*)(ivec+n);
&&&&&&&&&&&&&&&&&&&&*(size_t&*)(ivec+n)&=&c;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&len&-=&16;
&&&&&&&&&&&&&&&&in&&+=&16;
&&&&&&&&&&&&&&&&out&+=&16;
&&&&&&&&&&&&}
#endif&&&&
&&&&while&(len)&
//解密最后一个分组,或openssl定义了OPENSSL_SMALL_FOOTPRINT的话这里解密所有分组。与加密时基本一样,略
&&&&&&&&unsigned&char&c;
&&&&&&&&(*block)(in,&tmp.c,&key);
&&&&&&&&for(n=0;&n&16&&&&n&&++n)&{
&&&&&&&&&&&&c&=&in[n];
&&&&&&&&&&&&out[n]&=&tmp.c[n]&^&ivec[n];
&&&&&&&&&&&&ivec[n]&=&c;
&&&&&&&&if&(len&=16)&{
&&&&&&&&&&&&for&(;&n&16;&++n)
&&&&&&&&&&&&&&&&ivec[n]&=&in[n];
&&&&&&&&&&&&
&&&&&&&&len&-=&16;
&&&&&&&&in&&+=&16;
&&&&&&&&out&+=&16;
(2)CRYPTO_cfb128_encrypt&&CRYPTO_cfb128_1_encrypt&&CRYPTO_cfb128_8_encrypt
这三个实现了cfb模式的三种制式。其函数声明见上文描述。
这三种均被seed_cfb.c&&cmll_cfb.c&&aes_cfb.c引用。
在aes_cfb.c内使用情况如下:
void&AES_cfb128_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&&&size_t&length,&const&AES_KEY&*key,
&&&&&&&&&&&&&&&&&&&&&&&&unsigned&char&*ivec,&int&*num,&const&int&enc)&{
&&&&CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
/*&N.B.&This&expects&the&input&to&be&packed,&MS&bit&first&*/
void&AES_cfb1_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&size_t&length,&const&AES_KEY&*key,
&&&&&&&&&&&&&&&&&&&&&&unsigned&char&*ivec,&int&*num,&const&int&enc)
&&&&CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
void&AES_cfb8_encrypt(const&unsigned&char&*in,&unsigned&char&*out,
&&&&&&&&&&&&&&&&&&&&&&size_t&length,&const&AES_KEY&*key,
&&&&&&&&&&&&&&&&&&&&&&unsigned&char&*ivec,&int&*num,&const&int&enc)
&&&&CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);电脑编程技巧与维护
&你好,欢迎来到电脑编程技巧与维护杂志社!
硬件系统维护
您的位置: / 计算机安全与维护
IDEA对称密码算法剖析(一)
摘& 要& 学习算法的一种非常有效的方法就是分析经典算法的代码实现。IDEA算法是一种典型的对称密钥密码算法,是一种密钥长度为128位的分组密码算法,这种算法既可以用于加密,也可以用于解密,具有代码量少、运行速度快、安全性高等特点。本文首先剖析了IDEA算法原理,然后对基于VC++的IDEA算法的C++实例进行了解析。
关键词& IDEA;对称密码;分组密码;C语言
IDEA (International Data Encryption Algorithm:国际数据加密算法)是1990年由瑞士联邦技术学院的X.J.Lai 和Massey提出的PES(Proposed Encryption Standard:建议标准算法)的改进版本。于1992年命名为IDEA。IDEA对PES的抗差分分析的能力进行了强化处理,其安全性非常高,同一种算法既可以用于加密,又可以用于解密,其唯一的区别仅仅在于子密钥的生成方法不同。IDEA算法在诸如邮件加密系统PGP等多种商业产品中被广泛使用。
IDEA是一种分组长度为64位的分组密码算法,密钥长度为128位。128位的密钥用于产生52个子密钥。在整个加密过程中,总共需要进行8轮迭代运算,整个迭代过程需要48个子密钥,另外4个子密钥用于最终的64位密文的输出变换。
IEDA算法基于“相异代数群上的混合运算”的设计思想,其迭代运算中采用了三种数学运算:16位整数的模216加法运算、16位分组的按位异或运算和16位整数的模216+1乘法运算。为了叙述简洁,在后文中将直接称这三种运算为加法、乘法和异或运算。这三种运算中的任何一对运算都不满足分配律,也不满足结合律,这让它们的组合能对输入作出复杂的变换,从而使得攻击者无法使用化简的方式来分析明文及密钥之间的关系,因此,对IDEA算法的密码分析要比对只使用异或运算的DES算法的分析要困难得多。
2& 算法原理及框架
IDEA的加密过程包括两个部分:明文到密文加密的8轮迭代运算和子密钥的产生。
2.1 IDEA加密迭代运算
IDEA加密迭代运算过程如图1所示。输入的64位明文数据分组被分成4个16位的子分组,分别记为X1、X2、X3和X4。这四个分组作为算法的第一轮的输入,整个加密过程总共进行8轮迭代运算,最终产生64位的密文输出。
在图1中,每轮运算分为两部分。
&&推荐精品文章
││││││││││││││││││││││││
Copyright , .cn, All Rights Reserved
京ICP备号,电话/传真:010-561614 ,Mail:.cn
地址:北京市海淀区长春桥路5号6号楼1209室,邮编:100089 二次元同好交流新大陆
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
你以为我会眼睁睁地看着你去送死?No,我会闭上眼睛的。
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
Lai和Massey开发出IDEA加密算法雏形,称为PES,即"建议的加密标准"。第二年,根据有关专家对这一密码算法的分析结果,设计者对该算法进行了强化并称之为IPES,即"改进的建议加密标准"。该算法于1992年更名为IDEA,即"国际加密标准"。&&
IDEA算法的密钥长度为128位,针对64位的数据进行加密或解密操作.设计者尽可能使该算法不受差分密码分析的影响,XueJia&Lai已证明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轮。&&
密钥(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个子密钥,存放在ULONG16&Key[52]数组中,然后对这个52个子密钥进行换位操作,&&
 & & &原位置:6879450123 & & & &&
表中的原位置行的值代表该子密钥在原密钥数组中的位置,比如新密钥数组中的第0号子密钥为原来子密钥组中的第48号子密钥,对子密钥数组换位后,就需要对某些子密钥进行模216&1的乘法逆或模216加法逆的替换,详情见下表(位置是针对换位后的子密钥组)&
12781314192025&
263132373843444950&
03691215182124&&
273033363942454851&
需要变化的子密钥总共18&18&=&36个,另外的52&–&36&=&16个子密钥不变化.&&
下面介绍有关x逆元的计算方法.&
&x&-1&=&65536&–&x&&
X模216&1乘法法逆和X的关系如下:&&
(X*X-1&)&e537&=&1&&
#define&LOW16(x)&((x)&0xffff)&&
ULONG16&mulInv(&ULONG16&x)&&
ULONG16&t0,t1;&
ULONG16&q,y;&&
if&(&x&=1)&&
return&x;&&
t1&=&0x10001L/x;&
y&=&0x10001L%x;&
if(y&==&1)&&
return&LOW16(1-t1);&&
t0&=&q*t1;&
if(&x&==&1)&&
return&t0;&
t1&=&q*t0;&&
}while(&y&!=&1);&&
return&LOW16(1-t1);&&
3.4注意事项
由于在IDEA中采用了乘法运算,这就要考虑到两个乘数是否为0&的情况,如果两个乘数都为0,那么乘法运算结果为0,如果仅有一个乘数为0,那么用65536替换那个为0的乘数,取乘法运算结果的低16位作为输出结果.&&
INT32&MUL(&ULONG16&a,&ULONG16&b)/*(a*b)*/&
ULONG32&p;&&
if&(&a&==&0&&&&b&==&0&)&
else&if&(&a&==&0&)&
p&=&65536*(ULONG32)b;&&
else&if&(&b&==&0)&&
p&=&65536*(ULONG32)a;&
p&=&(ULONG32)a*(ULONG32)b;&
return&(ULONG16&)(pe537);&
3.5&算法实现代码
/*此处略去信息说明和头文件*/&&
#include&"idea.h"&
#define&NULL&((void&*)0)&
typedef&int&INT32;&&
typedef&char&INT8;&&
typedef&unsigned&char&ULONG8;&&
typedef&unsigned&short&ULONG16;&&
typedef&unsigned&long&ULONG32;&&
#define&SUCCESS&0&&
#define&FAIL&-1&
#define&LOW16(x)&((x)&0xffff)&
#define&_USEDFINDTABLE_&1&/*是否采用查表实现*/&&
/*解密时密钥的换位表*/&
&outkey[52]&=&{&0&};&&
static&ULONG8&wz_spkey[52]&=&{&
48,49,50,51,46,47,&
6,&8,&7,&9,&4,&5,/*解密密钥配置,2,3位要交换:8&-&7*/&&
0,&1,&2,&3&
static&ULONG8&wz_spmulrevr[18]&=&{/*变乘法逆的位*/&
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51&&
static&ULONG8&wz_spaddrever[18]&={/*变加法逆的位*/&
1,2,7,8,13,14,19,20,25,26,31,32,37,38,43,44,49,50&&
INT32&mulInv(&ULONG16&x);/*取x的(%0x10001L)乘法逆*/&&
INT32&handle_data(&ULONG16&*data,&/*待加密的64位数据首地址*/&&
ULONG16&*key&/*&6组本轮使用的16位长的密钥首地址*/&
INT32&idea_makekey(&ULONG32&*inkey,/*用户输入的128位密钥首地址*/&&
ULONG16&*outkey/*生成的52组16位密钥的首地址*/&
INT32&key_leftmove(ULONG32&*inkey);&
INT32&key_decryExp(ULONG16&*outkey);/*解密密钥的变逆处理*/&
INT32&MUL(&ULONG16&a,&ULONG16&b);/*(a*b)*/&
INT32&idea_dec(&ULONG16&*data,&/*待解密的64位数据首地址*/&&
ULONG16&*outkey&&
ULONG32&i&;&&
ULONG16&&&
if&(&NULL&==&data&||&NULL&==&outkey)&
return&FAIL;&&
for&(&i&=&0&;&i&&&48&;&i&=&6)/*8轮*/&
handle_data(&data&,&&outkey[i]);&&
/*交换中间两个*/&&
tmp&=&data[1];&
data[1]&=&data[2];&
data[2]&=&&&
tmp&=&data[1];/*最后一轮不交换*/&&
data[1]&=&data[2];&
data[2]&=&&
data[0]&=&MUL(data[0],outkey[48]);&
data[1]&=&outkey[49];&&
data[2]&=&outkey[50];&
data[3]&=&MUL(data[3],outkey[51]);&&
return&SUCCESS;&&
INT32&idea_enc(&ULONG16&*data,&/*待加密的64位数据首地址*/&&
ULONG16&*outkey&&
ULONG32&i&;&
ULONG16&&&
if&(&NULL&==&data&||&NULL&==&outkey)&
return&FAIL;&
for&(&i&=&0&;&i&&&48&;&i&=&6)/*8轮*/&&
handle_data(&data&,&&outkey[i]);&&
/*交换中间两个*/&
tmp&=&data[1];&&
data[1]&=&data[2];&
data[2]&=&&
tmp&=&data[1];/*最后一轮不交换*/&&
data[1]&=&data[2];&
data[2]&=&&
data[0]&=&MUL(data[0],outkey[48]);&
data[1]&=&outkey[49];&
data[2]&=&outkey[50];&
data[3]&=&MUL(data[3],outkey[51]);&&
return&SUCCESS;&
INT32&handle_data(&ULONG16&*data,&/*待加密的64位数据首地址*/&&
ULONG16&*key&/*&6组本轮使用的16位长的密钥首地址*/&&
ULONG16&*D1,*D2,*D3,*D4;&
ULONG16&D57;/*提供给第5,7步用的暂存数据的*/&
ULONG16&D68;/*提供给第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步*/&
return&SUCCESS;&&
INT32&idea_makekey(&ULONG32&*inkey,/*用户输入的128位密钥首地址*/&&
ULONG16&*outkey/*生成的52组16位密钥的首地址*/&
ULONG32&i,j,k;&&
ULONG16&*Pkey&=&(&ULONG16*)&&
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[i]&;&
return&SUCCESS;&
INT32&key_leftmove(ULONG32&*inkey)/*密钥左环移25位*/&
ULONG32&itmpfirst&=&0,itmp&=&0&;&
3.6&加密工具的实现
利用算法核心代码封装的接口函数笔者编写了一个加密工具,&IDEA算法是对固定大小(64位)的数据块进行加密解密操作的,对于那些不够64位的数据块需要采用填充机制补位到64位长,为了方便使用,数据位的填充是对用户而言是透明的,利用该工具进行加密解密操作时,用户只需输入操作的类型、读取数据的文件名、写入操作结果的文件名、密钥等信息.&&
#define&READFILESIZE&512&&
以二进制的形式从文件中读取READFILESIZE个字节的数据,如果从文件中读出的数据少于READFILESIZE个,以0补足,然后根据用户指定的类型对这READFILESIZE个字节的数据进行操作.&
判断文件是否结束,如果还没有介绍则返回执行步骤1&
把加密后的文件实际长度和读出数据的文件名加密后添加到密文的末尾&&
采用一次只从文件读取READFILESIZE个字节是在为了防止由于需要加密或解密的文件太大导致内存不够的情况出现.&&
使用该程序加密文件,用户不必记住加密前文件的类型,程序会在解密时自动将密文恢复成原文件的类型和长度.&
3.6.1&加密工具实现源代码
下面列出按照上述操作思路编写的实现源代码&&
/**********************************************************************/&&
/*-文件名:idea.c&*/&&
/*-功能:&利用idea加密算法实现文件的加密&*/&
/*-说明:&*/&
/*-&这是利用IDEA算法实现的文件加密工具可以在法律允许范围内以非商&*/&&
/*-业形式自由使用,该程序的所有权利由作者吴真保留&*/&
/*-版本号:1.0.0(2002.6)&*/&&*/&
/*********************************************************************/&&
#include&&
#include&&
#include&"idea.h"&&
typedef&int&INT32;&
typedef&char&INT8;&&
typedef&unsigned&char&ULONG8;&
typedef&unsigned&short&ULONG16;&&
typedef&unsigned&long&ULONG32;&&
#define&SUCCESS&0&
#define&FAIL&-1&&
#define&WZ_COMMEND_NUM&4&
#define&WZUSEHELPNUM&7&
#define&READFILESIZE&512&/*一次从文件中读取多少字节,可以根据内存的大小调节*/&&
INT32&file_enc(&FILE&*readfile,&FILE&*writefile,ULONG8&*key);/*加密文件*/&&
INT32&file_dec(&FILE&*readfile,&FILE&*writefile,ULONG8&*key);/*解密文件*/&
INT32&hextofile(&ULONG8&*buf&,FILE&*writefile,&ULONG32&length);/*以16进制写入文件*/&
INT32&encodehex(ULONG8&*tobuf,ULONG8&*frombuf,ULONG32&len);/*16进制解码*/&&
void&wz_printhelp();/*打印帮助*/&
INT8&*WZ_Commend_Help[]&=&&
"基于IDEA的加密解密工具v1.0&",/*0*/&
"追求卓越,勇于创新&",&
"----著者&:&吴真---&",&&
INT8&*WZ_USE_HELP[]={&
"输入5个参数:",&
"\t1.可执行文件名&*.exe",&
"\t2.操作类型&1:加密;2:解密;",&
"\t3.读出数据的文件名*.txt",&
"\t4.写入数据的文件名*.txt",&&
"\t5.密钥(32字节)",&
"******************************"&&
void&main(INT32&argc,INT8&*argv[])&&
INT8&*FILENAME1,*FILENAME2;&
FILE&*fp,&*fp2;&&
ULONG8&key[33]&=&{&0&};&/*密钥容器*/&&
if&(&argc&!=&5&)&
wz_printhelp();&
FILENAME1&=&argv[2];&&
FILENAME2&=&argv[3];&
if&((fp=&fopen(FILENAME1,"r&b"))&==&NULL&||&(fp2&=&fopen(FILENAME2,"w&b"))==NULL)&&
printf("Can't&open&file\n");&
return&;&&
memcpy(&key,&argv[4]&,&strlen(&argv[4])&);/*取得密钥*/&
switch(&atoi(argv[1]&))&&
case&1:/*加密操作*/&
file_enc(fp,fp2,key);&
printf("\n&\t&IDEA&加密完毕,密文存于%s文件\n",FILENAME2);&
file_dec(fp,fp2,key);&&
printf("\n\t&IDEA解密完毕,明文存于%s文件\n",FILENAME2);&&
printf("请选择是加密|解密&plese&choose&encrypt|deencrypt\n");&
fclose(fp);&&
fclose(fp2);&
INT32&hextofile(&ULONG8&*buf&,FILE&*writefile,&ULONG32&length)&&
ULONG32&writelen&=&0&;&
/*以16进制形式写入文件*/&
while(&writelen&&&length)&&
if(buf[writelen]&==&0)&&
fprintf(&writefile,&"%x",&0&);&&
fprintf(&writefile,&"%x",&0&);&&
else&if&(buf[writelen]&&&0x10)&&
fprintf(&writefile,&"%x",&0&);&&
fprintf(&writefile,&"%x",&buf[writelen]&);&&
fprintf(&writefile,&"%x",&buf[writelen]&);&&
writelen&;&&
return&SUCCESS;&&
INT32&file_enc(&FILE&*readfile,&FILE&*writefile,ULONG8&*key)&
INT32&filelen&=&0,readlen&=&0,writelen&=&0;&&
ULONG32&totalfilelen&=&0&;/*统计实际的文件的长度*/&
ULONG8&readbuf[READFILESIZE]&=&{&0&};&&
idea_makekey(&(ULONG32*)key&,&outkey);&&
filelen&=&fread(&readbuf,&sizeof(&INT8&),&READFILESIZE,&readfile&);&&
while(&filelen&==&READFILESIZE&)&
totalfilelen&=&READFILESIZE;&&
for&(&i&=&0&;&i&&&READFILESIZE&;&i&=&8)&&
idea_enc(&(ULONG16*)&readbuf[i]&);/*加密*/&&
hextofile(&readbuf,&writefile,&READFILESIZE&);/*以16进制形式写入文件*/&&
memset(readbuf,0,READFILESIZE);&
filelen&=&fread(&readbuf,&sizeof(&INT8&),&READFILESIZE,&readfile&);&
/*这是从文件中读出的最后一批数据,长度可能会等于0,所以要先判断*/&&
if&(&filelen&&&0&)&
/*如果从文件中读出的长度不等于0,那么肯定有8个字节以上的空间&&
文件长度存在最后8个字节中*/&&
totalfilelen&=&&&
memcpy(&&readbuf[READFILESIZE-8],&(ULONG8*)&totalfilelen,4);&&
for&(&i&=&0&;&i&&&READFILESIZE&;&i&=&8)&&
idea_enc(&(ULONG16*)&readbuf[i]);/*加密*/&
hextofile(&readbuf,&writefile,READFILESIZE&);/*以16进制形式写入文件*/
memset(readbuf,0&,READFILESIZE);
else&/*filelen&==&0*/&
memcpy(&&readbuf[0],&(ULONG8*)&totalfilelen,4);&&
idea_enc(&(ULONG16*)&readbuf[0]&);/*加密*/&
hextofile(&readbuf,&writefile,&8);/*以16进制形式写入文件*/&
return&SUCCESS;&
INT32&file_dec(&FILE&*readfile,&FILE&*writefile,ULONG8&*key)&
INT32&filelen&=&0,readlen&=&0,writelen&=&0;&&
ULONG32&totalfilelen&=&0&;/*统计实际的文件的长度*/&
INT32&i,&&
ULONG8&readbuf[READFILESIZE]&=&{&0&};&&
ULONG8&sendbuf[READFILESIZE*2]&=&{&0&};&&
idea_makekey(&(ULONG32*)key&,&outkey);&&
key_decryExp(outkey);&&
fseek(readfile,-16,SEEK_END);/*最后16个字节的表示文件长度的空间*/&
filelen&=&fread(&sendbuf,&sizeof(&INT8&),&16,&readfile&);&
encodehex(&readbuf,sendbuf,8);&&
idea_dec(&(ULONG16*)&readbuf[0]&);/*解密*/&&
memcpy((ULONG8*)&totalfilelen,&&readbuf[0],4);/*得到文件总长*/&&
memset(readbuf,0&,8);&&
memset(sendbuf,0&,16);&
num&=&totalfilelen/READFILESIZE;/*有几个READFILESIZE组*/&&
totalfilelen&%=&READFILESIZE;&&
fseek(readfile,0,SEEK_SET);/*跳到文件头*/&&
while(num--)&&
filelen&=&fread(&sendbuf,&sizeof(&INT8&),&READFILESIZE*2,&readfile&);&&
encodehex(&readbuf,sendbuf,READFILESIZE);&&
for&(&i&=&0&;&i&&&READFILESIZE&;&i&=&8)&
idea_dec(&(ULONG16*)&readbuf[i]&);/*解密*/&&
writelen&=&fwrite(readbuf,&sizeof(&INT8&),&READFILESIZE,&writefile);&&
memset(readbuf,0&,READFILESIZE);&&
memset(sendbuf,0&,READFILESIZE*2);&
if&(&totalfilelen&&&0&)/*最后一块有多余的元素*/&
filelen&=&fread(&sendbuf,&sizeof(&INT8&),&READFILESIZE*2,&readfile&);&
encodehex(&readbuf,sendbuf,READFILESIZE);&&
for&(&i&=&0&;&i&&&READFILESIZE&;&i&=&8)&&
idea_dec(&(ULONG16*)&readbuf[i]&);/*解密*/&
writelen&=&fwrite(readbuf,&sizeof(&INT8&),&totalfilelen,&writefile);&&
memset(readbuf,0&,READFILESIZE);&
memset(sendbuf,0&,READFILESIZE*2);&
return&SUCCESS;&
INT32&encodehex(ULONG8&*tobuf,ULONG8&*frombuf,ULONG32&len)&
ULONG8&*readfirst&=&frombuf&;&
ULONG8&*readend&=&&frombuf[1]&;&&
ULONG8&y[2]&;&
ULONG32&i;&&
for&(&i&=&0&;&i&&&len&;&i&)&
y[0]&=&*readfirst&;&
y[1]&=&*readend&;&&
readfirst&=&2&;&&
readend&=&2&;&
tobuf[i]&=&(ULONG8)strtol((INT8*)y,&&s,&16);&&
return&SUCCESS;&&
void&wz_printhelp()&
INT32&i&;&&
printf("\t");&&
for&(&i&=&0&;&i&&&22&;&i&)&&
printf("%c&",5);&&
printf("\n");&&
for(&i&=&0&;&i&&&WZ_COMMEND_NUM&;&i&)&&
printf("\t%c\t%s&%c\n",5,WZ_Commend_Help[i],5);&
printf("\t");&&
for&(&i&=&0&;&i&&&22&;&i&)&
printf("%c&",5);&
printf("\n");&
for(&i&=&0&;&i&&&WZUSEHELPNUM&;&i&)&
printf("\t%s\n",WZ_USE_HELP[i]);&
阅读(2946)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'IDEA算法',
blogAbstract:'IDEA算法Lai和Massey开发出IDEA加密算法雏形,称为PES,即\"建议的加密标准\"。第二年,根据有关专家对这一密码算法的分析结果,设计者对该算法进行了强化并称之为IPES,即\"改进的建议加密标准\"。该算法于1992年更名为IDEA,即\"国际加密标准\"。&&
IDEA算法的密钥长度为128位,针对64位的数据进行加密或解密操作.设计者尽可能使该算法不受差分密码分析的影响,XueJia&Lai已证明IDEA算法在其8轮迭代的第4圈之后便不受差分密码分析的影响了。假定穷举法攻击有效的话,那么即使设计一种每秒种可以试验10亿个密钥的专用芯片,并将10亿片这样的芯片用于此项工作,仍需1013年才能解决问题;另一方面,若用1024片这样的芯片,有可能在一天内找到密钥,不过人们还无法找到足够的硅原子来制造这样一台机器',
blogTag:'编程,学习',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:5,
publishTime:3,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'你以为我会眼睁睁地看着你去送死?No,我会闭上眼睛的。',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}}

我要回帖

更多关于 密码算法有哪些 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信