标题：RC5
相关介绍
简介RC5分组密码算法是1994由麻萨诸塞技术研究所的Ronald L. Rivest教授发明的，并由RSA实验室分析。它是参数可变的分组密码算法，三个可变的参数是：分组大小、密钥大小和加密轮数。在此算法中使用了三种运算：异或、加和循环。
RC5是种比较新的算法，Rivest设计了RC5的一种特殊的实现方式，因此RC5算法有一个面向字的结构：RC5-w/r/b，这里w是字长其值可以是16、32或64对于不同的字长明文和密文块的分组长度为2w位，r是加密轮数，b是密钥字节长度。由于RC5一个分组长度可变的密码算法，为了便于说明在本文中主要是针对64位的分组w=32进行处理的，下面详细说明了RC5加密解密的处理过程：加密解密1、创建密钥组
RC5算法加密时使用了2r+2个密钥相关的的32位字： ，这里r表示加密的轮数。创建这个密钥组的过程是非常复杂的但也是直接的，首先将密钥字节拷贝到32位字的数组L中(此时要注意处理器是little-endian顺序还是big-endian顺序)，如果需要，最后一个字可以用零填充。然后利用线性同余发生器模2初始化数组S：
对于i=1到2(r+1)-1： （本应模 ，本文中令w=32）
其中对于16位字32位分组的RC5，P=0xb7e1 Q=0x9e37
对于32位字和64位分组的RC5，P=0xb7e15163 Q=0x9e3779b9
对于64位字和128位分组，P=0xb7151628aed2a6b Q=0x9e3779b97f4a7c15
最后将L与S混合，混合过程如下：
i=j=0
A=B=0
处理3n次（这里n是2(r+1)和c中的最大值，其中c表示输入的密钥字的个数）
2、加密处理
在创建完密钥组后开始进行对明文的加密，加密时，首先将明文分组划分为两个32位字：A和B（在假设处理器字节顺序是little-endian、w=32的情况下，第一个明文字节进入A的最低字节，第四个明文字节进入A的最高字节，第五个明文字节进入B的最低字节，以此类推），其中操作符<<<表示循环左移，加运算是模 （本应模 ，本文中令w=32）的。
输出的密文是在寄存器A和B中的内容
3、解密处理
解密也是很容易的，把密文分组划分为两个字：A和B（存储方式和加密一样），这里符合>>>是循环右移，减运算也是模 （本应模 ，本文中令w=32）的。
RSA试验室花费了相当的时间来分析64位分组的RC5算法，在5轮后统计特性看起来非常好。在8轮后，每一个明文位至少影响一个循环。对于5轮的RC5，差分攻击需要 个选择明文；对10轮需要 个；对于12轮需要 个；对15轮需要 个。而对于64位的分组只有 个可能的明文，所以对于15轮或以上的RC5的差分攻击是失败的。在6轮后线性分析就是安全的了，Rivest推荐至少12轮，甚至可能是16轮。这个轮数可以进行选择。
参考例子
rfc 2040文档中列出了RC5算法密钥生成和加密实现的C代码，在此笔者参照文档中定义的算法结构，编写了用于对密文解密的程序代码（此代码经多次测试运行良好），供读者参考。宏定义1、补充了两个个宏定义：
#define SHL1(x,s,w) ((RC5_WORD)((x)<<((w)-((s)&ROT_MASK))))
#define ROTR(x,s,w) ((RC5_WORD)(SHR1((x),(s))|SHL1((x),(s),(w))))函数定义2、解密函数定义如下：
void RC5_Block_Decrypt (RC5_WORD *S,int R,char *in,char *out)
{
int i;
RC5_WORD A,B;
A = in[0] & 0xFF;
A += (in[1] & 0xFF) << 8;
A += (in[2] & 0xFF) << 16;
A += (in[3] & 0xFF) << 24;
B = in[4] & 0xFF;
B += (in[5] & 0xFF) << 8;
B += (in[6] & 0xFF) << 16;
B += (in[7] & 0xFF) << 24;
for(i=R;i>=1;i--){
B=ROTR((B-S[2*i+1]),A,W);
B=B^A;
A=ROTR((A-S[2*i]),B,W);
A=A^B;
}
B=B-S[1];
A=A-S[0];
out[0] = (A >> 0) & 0xFF;
out[1] = (A >> 8) & 0xFF;
out[2] = (A >> 16) & 0xFF;
out[3] = (A >> 24) & 0xFF;
out[4] = (B >> 0) & 0xFF;
out[5] = (B >> 8) & 0xFF;
out[6] = (B >> 16) & 0xFF;
out[7] = (B >> 24) & 0xFF;
return;
}/*End of RC5_Block_Decrypt */
int RC5_CBC_Decrypt_Init (pAlg, pKey)
rc5CBCAlg *pAlg;
rc5UserKey *pKey;
{
if ((pAlg == ((rc5CBCAlg *) 0)) ||
(pKey == ((rc5UserKey *) 0)))
return (0);
RC5_Key_Expand (pKey->keyLength, pKey->keyBytes,pAlg->R, pAlg->S);
return (RC5_CBC_SetIV(pAlg, pAlg->I));
}
int RC5_CBC_Decrypt_Update(rc5CBCAlg *pAlg,int N,char *C,int *plainLen,char *P)
{
int plainIndex,cipherIndex,j;
plainIndex=cipherIndex=0;
for(j=0;j<BB;j++)
{ 
P[plainIndex]=pAlg->chainBlock[j];
plainIndex++;
}
plainIndex=0;
while(cipherIndex<N)
{ 
if(pAlg->inputBlockIndex<BB)
{
pAlg->inputBlock[pAlg->inputBlockIndex]=C[cipherIndex];
pAlg->inputBlockIndex++;
cipherIndex++;
}
if(pAlg->inputBlockIndex==BB)
{ 
pAlg->inputBlockIndex=0; 
RC5_Block_Decrypt (pAlg->S,pAlg->R,pAlg->inputBlock,pAlg->chainBlock);
for(j=0;j<BB;j++)
{
if(plainIndex<BB)
P[plainIndex]^=pAlg->chainBlock[j];
else 
P[plainIndex]=C[cipherIndex-16+j]^pAlg->chainBlock[j];
plainIndex++;
}
}
} 
*plainLen=plainIndex;
return (1);
}/*End of RC5_CBC_Decrypt_Update*/
常见密码模式
以上的操作只是针对的一个明文分组的，对于分组加密算法有以下几种比较常见的分组密码模式：电子密码本电子密码本（Electronic Code Book,，ECB）模式是使用分组密码算法的最明显的方式，其使用方式是一个明文分组加密成一个密文分组，相同的明文分组永远被加密成相同的密文分组，在理论上制造这样的一个密码本是可行的，但实际上要进行大量的预计算耗费存储空间，最容易的运行模式是每个明文分组可被独立地进行加密，但受分组重放攻击。密码分组链接密码分组链接模式（Cipher Block Chaining，CBC）模式中，明文被加密之前要与前面的密文进行异或运算，如果前面的明文分组不同才能将完全相同的明文分组加密成不同的密文分组，这会给密码分析者提供有用的线索，为了防止这种情况发生使用一个随机数据分组作为加密的第一个分组叫作初始化向量（initialization Vector，IV），这样就可以把完全相同的信息加密成不同的密文消息。密码反馈密码反馈模式（Cipher-Feedback，CFB）是把分组密码算法用于自同步序列密码的一种方法，在CBC模式下，整个数据分组在接收完之后才能进行加密，在此模式下数据可以在比分组小的多的单元里进行处理。输出反馈输出反馈模式（Output-Feedback，OFB）是将分组密码用于同步序列密码运行的一种方法，它有一个很好的特性就是在明文存在前的大部分工作可以离线进行。以上几种模式中密码分组链接模式是在安全协议中使用的最为普遍，在无线应用协议中安全层定义的分组加密算法都是CBC模式。几大手机厂家如Nokia，Motorala，Erison的WAP手机的首选的分组加密算法就是RC5