RC4加密算法是大名鼎鼎的RSA三人組中的頭號人物Ronald Rivest在1987年設計的密鑰長度可變的流加密算法簇。之所以稱其爲簇,是由於其核心部分的S-box長度可爲任意,但一般爲256字節。該算法的速度可以達到DES加密的10倍左右,且具有很高級別的非線性。RC4起初是用於保護商業機密的。但是在1994年9月,它的算法被髮布在互聯網上,也就不再有什麼商業機密了。RC4也被叫做ARC4(Alleged RC4——所謂的RC4),因爲RSA從來就沒有正式發佈過這個算法。
RC4算法的原理很簡單,包括初始化算法(KSA)和僞隨機子密碼生成算法(PRGA)兩大部分。假設S-box的長度爲256,密鑰長度爲Len。
在初始化的過程中,祕鑰的主要功能是將S-box攪亂,i確保S-box的每個元素都得到處理,j保證S-box的攪亂是隨機的。而不同的S-box在經過僞隨機子密碼生成算法的處理後可以得到不同的子祕鑰序列,將S-box和明文進行xor運算,得到密文,解密過程也完全相同。
程序:(將ARM的指定文件的明文按行加密成密文,再次運行密文將按行解爲明文)
#include<stdio.h>
#include<memory.h>
#include<string.h>
#include<stdlib.h>
#define buf_size 1024 //讀取明文的最大字節數
typedef struct rc4_key //存放密鑰序列
{
unsigned char state[256];
unsigned char x;
unsigned char y;
} rc4_key;
typedef struct rc4_mkey //備份密鑰序列
{
unsigned char state[256];
unsigned char x;
unsigned char y;
} rc4_mkey;
#define swap_byte(x,y) t = *(x); *(x) = *(y); *(y) = t
void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key) //初始化函數
{
int i;
unsigned char t;
unsigned char swapByte;
unsigned char index1;
unsigned char index2;
unsigned char* state;
short counter;
state = &key->state[0];
for(counter = 0; counter < 256; counter++)
{
state[counter] = counter;
}
key->x = 0;
key->y = 0;
index1 = 0;
index2 = 0;
for(counter = 0; counter < 256; counter++)
{
index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
swap_byte(&state[counter], &state[index2]);
index1 = (index1 + 1) % key_data_len;
}
}
void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) //加解密
{
unsigned char t;
unsigned char x;
unsigned char y;
unsigned char* state;
unsigned char xorIndex;
short counter;
x = key->x;
y = key->y;
state = &key->state[0];
for(counter = 0; counter < buffer_len; counter++)
{
x = (x + 1) % 256;
y = (state[x] + y) % 256;
swap_byte(&state[x], &state[y]);
xorIndex = (state[x] + state[y]) % 256;
buffer_ptr[counter] ^= state[xorIndex];
}
key->x = x;
key->y = y;
}
void coding_rc4()
{
char seed[256];
char data[512] = {"just123"}; //密鑰
char fname[512] = {"/mnt/key.txt"}; //加密文件路徑
char *tn;
char buf[buf_size];
char num[10];
char digit[5];
int hex, rd,i;
int n;
rc4_key key; //密鑰序列結構體
rc4_mkey mkey; //備份密鑰序列結構體
FILE *fp,*des;
n = strlen(data); //讀取密鑰長度
if(n>512) //對密鑰進行處理使之更好的可是別
{
fprintf(stderr,"can't tolerate key longer than 512 characters./n");
exit(1);
}
if (n&1) //n is odd number
{
strcat(data,"0");
n++; //convert n to even number
}
n/=2;
memset(digit,0,5*sizeof(char));
strcpy(digit,"AA");
for (i=0;i<n;i++)
{
digit[2] = data[i*2];
digit[3] = data[i*2+1];
sscanf(digit,"%x",&hex); //characters in the file key.txt are better to be recognizable hex numbers
seed[i] = hex; //only reserve the two lower hex numbers in varible 'hex'
}
prepare_key(seed,n,&key); //將我們設定好的祕鑰對state數組進行攪亂,得到祕鑰序列。
strcpy(mkey.state,key.state); //備份密鑰序列,後面加密時密鑰序列將被打亂
mkey.x = key.x;
mkey.y = key.y;
if((fp=fopen(fname,"r"))==NULL) //打開加密文件
{
exit(1);
}
tn=strdup(fname);
strcat(fname,".en");
if((des=fopen(fname,"w"))==NULL) //打開備份加密文件
{
exit(1);
}
fgets(buf,60,fp); //讀取明文第一行
rd = strlen(buf); //讀取第一行長度,便於後面的處理
if(buf[rd-2]=='\r') //win7下換行爲\r\n linux下爲\n
{
rd = rd - 1;
}
buf[rd-1] = '\0';
rc4(buf,rd-1,&key); //加密第一行明文
fgets(num,60,fp); //讀取第二行明文
rd = strlen(num);
if(num[rd-1]!='\n') //同上處理
{
rd = rd + 1;
}
num[rd-1] = '\0';
strcpy(key.state,mkey.state); //回覆被打亂的密鑰序列
key.x = mkey.x;
key.y = mkey.y;
rc4(num,rd-1,&key); //加密第二行明文
strcat(buf,"\n");
strcat(buf,num);
strcat(buf,"\n");
fwrite(buf,1,60,des); //將加密的一二行寫入備份文件
fclose(fp);
fclose(des);
sprintf(fname,"rm %s",tn); //刪除原明文文件,用密文文件替代
system(fname);
sprintf(fname,"mv %s.en %s",tn,tn);
system(fname);
}
int main()
{
coding_rc4();
}
要注意的是,如果用該程序的RC4()函數那祕鑰序列要先進行備份,調用RC4()後祕鑰序列將會被打亂,導致下次的祕鑰序列和這次的不同,所以備份後下次再調用RC4()函數時進行恢復,使每次加密的祕鑰序列相同。
按行加密要注意的是提取出行信息後要去掉換行符,換行符在win7下是\r\n、在linux下爲\n。去掉換行符後對行裏的內容進行加解密,這樣才能更準確。
漏洞:(摘錄於百度百科)
由於RC4算法加密是採用的xor,所以,一旦子密鑰序列出現了重複,密文就有可能被破解。關於如何破解xor加密,請參看Bruce Schneier的Applied Cryptography一書的1.4節Simple XOR,在此我就不細說了。那麼,RC4算法生成的子祕鑰序列是否會出現重複呢?由於存在部分弱密鑰,使得子密鑰序列在不到100萬字節內就發生了完全的重複,如果是部分重複,則可能在不到10萬字節內就能發生重複,因此,推薦在使用RC4算法時,必須對加密密鑰進行測試,判斷其是否爲弱密鑰。其不足主要體現於,在無線網絡中IV(初始化向量)不變性漏洞。
--------------------------------------------------------------海魚