C版RC4加密解密函数库

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的基础上实现一些变种达到随机数据包的功能,这儿就不多说了。

Leave a comment

Your email address will not be published. Required fields are marked *