标签:
RC5分组密码算法是1994由麻萨诸塞技术研究所的Ronald L. Rivest教授发明的,并由RSA实验室分析。它是参数可变的分组密码算法,三个可变的参数是:分组大小、密钥大小和加密轮数。在此算法中使用了三种运算:异或、加和循环。
RC5是种比较新的算法,Rivest设计了RC5的一种特殊的实现方式,因此RC5算法有一个面向字的结构:RC5-w/r/b,这里w是字长其值可以是16、32或64对于不同的字长明文和密文块的分组长度为2w位,r是加密轮数,b是密钥字节长度。RC5是一个分组长度可变的密码算法.
加密解密
1、创建密钥组
RC5算法加密时使用了2r+2个密钥相关的的32位字: 这里r表示加密的轮数。
2、加密处理
在创建完密钥组后开始进行对明文的加密。
3、解密处理
RSA试验室花费了相当的时间来分析64位分组的RC5算法,在5轮后统计特性看起来非常好,在6轮后线性分析就是安全的了。在8轮后,每一个明文位至少影响一个循环。Rivest推荐至少12轮,甚至可能是16轮。轮数可以进行选择,一般是8轮、12轮或16轮。
代码如下(在实际项目中经过大量测试过):
RC5加密算法头文件
#ifndef _MY_RC5_H #define _MY_RC5_H #include <stdlib.h> #define RC5_ENCRYPT 1 #define RC5_DECRYPT 0 /* 32 bit. For Alpha, things may get weird */ #define RC5_32_INT unsigned int #define RC5_32_BLOCK 8 #define RC5_32_KEY_LENGTH 16 /* This is a default, max is 255 */ /* This are the only values supported. Tweak the code if you want more * * The most supported modes will be * * RC5-32/12/16 * * RC5-32/16/8 * */ #define RC5_8_ROUNDS 8 #define RC5_12_ROUNDS 12 #define RC5_16_ROUNDS 16 typedef struct rc5_key_st { /* Number of rounds */ int rounds; RC5_32_INT data[2*(RC5_16_ROUNDS+1)]; } RC5_32_KEY; #define c2ln(c,l1,l2,n) { c+=n; l1=l2=0; switch (n) { case 8: l2 =((RC5_32_INT )(*(--(c))))<<24L; case 7: l2|=((RC5_32_INT )(*(--(c))))<<16L; case 6: l2|=((RC5_32_INT )(*(--(c))))<< 8L; case 5: l2|=((RC5_32_INT )(*(--(c)))); case 4: l1 =((RC5_32_INT )(*(--(c))))<<24L; case 3: l1|=((RC5_32_INT )(*(--(c))))<<16L; case 2: l1|=((RC5_32_INT )(*(--(c))))<< 8L; case 1: l1|=((RC5_32_INT )(*(--(c)))); } } #undef c2l #define c2l(c,l) (l =((RC5_32_INT )(*((c)++))) , l|=((RC5_32_INT )(*((c)++)))<< 8L, l|=((RC5_32_INT )(*((c)++)))<<16L, l|=((RC5_32_INT )(*((c)++)))<<24L) #define RC5_32_MASK 0xffffffffL #define RC5_16_P 0xB7E1 #define RC5_16_Q 0x9E37 #define RC5_32_P 0xB7E15163L #define RC5_32_Q 0x9E3779B9L #define RC5_64_P 0xB7E151628AED2A6BLL #define RC5_64_Q 0x9E3779B97F4A7C15LL #define ROTATE_l32(a,n) (((a)<<(int)(n))|((a)>>(32-(int)(n)))) #define ROTATE_r32(a,n) (((a)>>(int)(n))|((a)<<(32-(int)(n)))) /* * #define ROTATE_l32(a,n) _lrotl(a,n) * #define ROTATE_r32(a,n) _lrotr(a,n) * */ #define E_RC5_32(a,b,s,n) a^=b; a=ROTATE_l32(a,b); a+=s[n]; a&=RC5_32_MASK; b^=a; b=ROTATE_l32(b,a); b+=s[n+1]; b&=RC5_32_MASK; #define D_RC5_32(a,b,s,n) b-=s[n+1]; b&=RC5_32_MASK; b=ROTATE_r32(b,a); b^=a; a-=s[n]; a&=RC5_32_MASK; a=ROTATE_r32(a,b); a^=b; typedef void (* f_RC5_32_decrypt)(RC5_32_INT *d, RC5_32_KEY *key); typedef void (* f_RC5_32_encrypt)(RC5_32_INT *d, RC5_32_KEY *key); typedef void (* f_RC5_32_set_key)(RC5_32_KEY *key, int len, const unsigned char *data, int rounds); #endif
RC5 加密算法源文件
//设置密钥
void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, int rounds) { RC5_32_INT L[64],l,ll,A,B,*S,k; int i,j,m,c,t,ii,jj; if ( (rounds != RC5_16_ROUNDS) && (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) rounds=RC5_16_ROUNDS; key->rounds=rounds; S= &(key->data[0]); j=0; for (i=0; i<=(len-8); i+=8) { c2l(data,l); L[j++]=l; c2l(data,l); L[j++]=l; } ii=len-i; if (ii) { k=len&0x07; c2ln(data,l,ll,k); L[j+0]=l; L[j+1]=ll; } c=(len+3)/4; t=(rounds+1)*2; S[0]=RC5_32_P; for (i=1; i<t; i++) S[i]=(S[i-1]+RC5_32_Q)&RC5_32_MASK; j=(t>c)?t:c; j*=3; ii=jj=0; A=B=0; for (i=0; i<j; i++) { k=(S[ii]+A+B)&RC5_32_MASK; A=S[ii]=ROTATE_l32(k,3); m=(int)(A+B); k=(L[jj]+A+B)&RC5_32_MASK; B=L[jj]=ROTATE_l32(k,m); if (++ii >= t) ii=0; if (++jj >= c) jj=0; } } //加密函数 void RC5_32_encrypt(RC5_32_INT *d, RC5_32_KEY *key) { RC5_32_INT a,b,*s; s=key->data; a=d[0]+s[0]; b=d[1]+s[1]; E_RC5_32(a,b,s, 2); E_RC5_32(a,b,s, 4); E_RC5_32(a,b,s, 6); E_RC5_32(a,b,s, 8); E_RC5_32(a,b,s,10); E_RC5_32(a,b,s,12); E_RC5_32(a,b,s,14); E_RC5_32(a,b,s,16); if (key->rounds == 12) { E_RC5_32(a,b,s,18); E_RC5_32(a,b,s,20); E_RC5_32(a,b,s,22); E_RC5_32(a,b,s,24); } else if (key->rounds == 16) { /* Do a full expansion to avoid a jump */ E_RC5_32(a,b,s,18); E_RC5_32(a,b,s,20); E_RC5_32(a,b,s,22); E_RC5_32(a,b,s,24); E_RC5_32(a,b,s,26); E_RC5_32(a,b,s,28); E_RC5_32(a,b,s,30); E_RC5_32(a,b,s,32); } d[0]=a; d[1]=b; } //解密函数 void RC5_32_decrypt(RC5_32_INT *d, RC5_32_KEY *key) { RC5_32_INT a,b,*s; s=key->data; a=d[0]; b=d[1]; if (key->rounds == 16) { D_RC5_32(a,b,s,32); D_RC5_32(a,b,s,30); D_RC5_32(a,b,s,28); D_RC5_32(a,b,s,26); /* Do a full expansion to avoid a jump */ D_RC5_32(a,b,s,24); D_RC5_32(a,b,s,22); D_RC5_32(a,b,s,20); D_RC5_32(a,b,s,18); } else if (key->rounds == 12) { D_RC5_32(a,b,s,24); D_RC5_32(a,b,s,22); D_RC5_32(a,b,s,20); D_RC5_32(a,b,s,18); } D_RC5_32(a,b,s,16); D_RC5_32(a,b,s,14); D_RC5_32(a,b,s,12); D_RC5_32(a,b,s,10); D_RC5_32(a,b,s, 8); D_RC5_32(a,b,s, 6); D_RC5_32(a,b,s, 4); D_RC5_32(a,b,s, 2); d[0]=a-s[0]; d[1]=b-s[1]; }
加密解密封装头文件
//声明加密函数 extern void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,int rounds); extern void RC5_32_encrypt(RC5_32_INT *d, RC5_32_KEY *key); extern void RC5_32_decrypt(RC5_32_INT *d, RC5_32_KEY *key); class CEncrypt { public: CEncrypt(); enum encMethod { ENCDEC_NONE, ENCDEC_RC5 }; void setEncMethod(encMethod method); void set_key_rc5(const unsigned char *data, int nLen, int rounds); int encdec(void *data, unsigned int nLen, bool enc); private: RC5_32_KEY key_rc5; bool haveKey_rc5; encMethod method; unsigned int enc_mask;//需要加密的位置(默认都所有位置需要加密和解密,每比特标示需要加密8字节,依次循环) unsigned int dec_mask;//需要解密的位置(跟加密位置一致) }; //加密解密封装源文件 CEncrypt::CEncrypt() { bzero(&key_rc5, sizeof(key_rc5)); haveKey_rc5 = false; method = ENCDEC_NONE; enc_mask = dec_mask = 0; } //设置加密方式 void CEncrypt::setEncMethod(encMethod m) { method = m; enc_mask = dec_mask = RC5_32_MASK;//0xffffffffL } void CEncrypt::setEncMask(unsigned int m) { enc_mask = m; } void CEncrypt::setDecMask(unsigned int m) { dec_mask = m; } void CEncrypt::set_key_rc5(const unsigned char *data, int nLen, int rounds = RC5_8_ROUNDS) { ::RC5_32_set_key(&key_rc5, nLen, data, rounds); haveKey_rc5 = true; } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) int CEncrypt::encdec_rc5(unsigned char *data, unsigned int nLen, bool enc) { if (0==data) return -1; unsigned int offset = 0; while (offset<=nLen-8) { RC5_32_INT d[2]; if (0x80000000 & (enc?enc_mask:dec_mask)) { memcpy(d, data+offset, sizeof(d)); if (enc) RC5_32_encrypt(d, &key_rc5); else RC5_32_decrypt(d, &key_rc5); memcpy(data+offset, d, sizeof(d)); } offset += sizeof(d);//后移8字节 if (enc) enc_mask = ROTATE_LEFT(enc_mask, 1);//循环左移 else dec_mask = ROTATE_LEFT(dec_mask, 1); } return nLen-offset; } int CEncrypt::encdec(void *data, unsigned int nLen, bool enc) { if (ENCDEC_NONE==method) return -1; if (ENCDEC_RC5==method) return encdec_rc5((unsigned char *)data, nLen, enc); return -2; }
int main() { unsigned char key[16] = { 0x3f,0x79,0xd5,0xe2,0x4a,0x8c,0xb6,0xc1,0xaf,0x31,0x5e,0xc7,0xeb,0x9d,0x6e,0xcb};//加密密钥 CEncrypt enc; /**< 加密接口 */ enc.set_key_rc5((const unsigned char *)key, 16, 12);//加密密钥和轮数 unsigned char toEncrypt[16] = {0}; snprintf(toCEncrypt,sizeof(toCEncrypt),"123456789012345");//加密前 printf("before Encrypt %s",toCEncrypt); enc.encdec(toEncrypt,sizeof(toEncrypt),true);//加密 printf("after Encrypt %s",toCEncrypt); enc.encdec(toEncrypt,sizeof(toEncrypt),false);//解密 printf("after decrypt %s",toCEncrypt); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/chenjiayi_yun/article/details/46840835