RC4是对称加密中比较好的加密算法,通过维护一个256长度的状态表实现一种基于密码的异或加密。下面是最近写的一个标准的RC4加密函数库,解密使用同样的函数即可。
/** RC4加密解密函数 @auhtor Hoverlees http://www.hoverlees.com */ #ifndef _RC4_H #define _RC4_H typedef struct rc4_context{ unsigned char sbox[256]; }rc4_context; /** * 初始化RC4状态表 * @param context RC4上下文 * @param key 加密密钥 * @param keyLen 密钥长度,如果为-1,程序通过strlen去计算长度 */ void rc4_init(rc4_context* context,const char* key,int keyLen); /** * RC4加密 * @param context 上下文 * @param data 要加密的数据 * @param dataLen 数据长度,如果data为字符串,该值可以为-1 * @param out 加密后保存的缓存,长度必须大于等于dataLen * @return 加密后的数据长度,一般为dataLen */ int rc4_crypt(rc4_context* context,const char* data,int dataLen,char* out); /** * RC4一次性加密 * @param key 密钥 * @param keyLen 密钥长度,如果密钥为字符串,该值可为-1 * @param data 要加密的数据 * @param dataLen 数据长度,如果data为字符串,该值可以为-1 * @param out 加密后保存的缓存,长度必须大于等于dataLen * @return 加密后的数据长度,一般为dataLen */ int rc4_crypt_once(const char* key,int keyLen,const char* data,int dataLen,char* out); #endif
#include "rc4.h" #include <string.h> void rc4_init(rc4_context* context,const char* key,int keyLen){ int i,j; char t; if(keyLen<0) keyLen=strlen(key); for(i=0;i<256;i++){ context->sbox[i]=i; } for(i=j=0;i<256;i++){ j=(j+key[i%keyLen]+context->sbox[i])%256; t=context->sbox[i]; context->sbox[i]=context->sbox[j]; context->sbox[j]=t; } } int rc4_crypt(rc4_context* context,const char* data,int dataLen,char* out){ int i=0; int j=0; int ti,x; char t; if(dataLen<0) dataLen=strlen(data); for(x=0;x<dataLen;x++){ i=(i+1)%256; j=(j+context->sbox[i])%256; t=context->sbox[i]; context->sbox[i]=context->sbox[j]; context->sbox[j]=t; ti=(context->sbox[i]+(context->sbox[j]%256))%256; t=context->sbox[ti]; out[x]=data[x]^t; } return dataLen; } int rc4_crypt_once(const char* key,int keyLen,const char* data,int dataLen,char* out){ rc4_context context; rc4_init(&context,key,keyLen); return rc4_crypt(&context,data,dataLen,out); }
RC4有一个缺点就是如果密钥和数据不变,得到的加密结果也一定是同一个。可以在RC4的基础上实现一些变种达到随机数据包的功能,这儿就不多说了。