给RC4加密的方法
#include "rc4.h" /* uncomment the following line to run the test suite */ /* #define TEST */ void rc4_setup( struct rc4_state *s, unsigned char *key, int length ) { int i, j, k, *m, a; s->x = 0; s->y = 0; m = s->m; for( i = 0; i < 256; i++ ) { m[i] = i; } j = k = 0; for( i = 0; i < 256; i++ ) { a = m[i]; j = (unsigned char) ( j + a + key[k] ); m[i] = m[j]; m[j] = a; if( ++k >= length ) k = 0; } } void rc4_crypt( struct rc4_state *s, unsigned char *data, int length ) { int i, x, y, *m, a, b; x = s->x; y = s->y; m = s->m; for( i = 0; i < length; i++ ) { x = (unsigned char) ( x + 1 ); a = m[x]; y = (unsigned char) ( y + a ); m[x] = b = m[y]; m[y] = a; data[i] ^= m[(unsigned char) ( a + b )]; } s->x = x; s->y = y; } #ifdef TEST #include <string.h> #include <stdio.h> /* *
*/ static unsigned char keys[7][30]={ {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, {8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {4,0xef,0x01,0x23,0x45}, {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, {4,0xef,0x01,0x23,0x45}, }; static unsigned char data_len[7]={8,8,8,20,28,10}; static unsigned char data[7][30]={ {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff}, {0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, 0x12,0x34,0x56,0x78,0xff}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, {0}, }; static unsigned char output[7][30]={ {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00}, {0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00}, {0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00}, {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf, 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba, 0x36,0xb6,0x78,0x58,0x00}, {0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89, 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c, 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87, 0x40,0x01,0x1e,0xcf,0x00}, {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00}, {0}, }; int main( void ) { int i; struct rc4_state s; unsigned char buffer[30]; printf( "/n RC4 Validation Tests:/n/n" ); for( i = 0; i < 6; i++ ) { printf( " Test %d ", i + 1 ); memcpy( buffer, data[i], data_len[i] ); rc4_setup( &s, &keys[i][1], keys[i][0] ); rc4_crypt( &s, buffer, data_len[i] ); if( memcmp( buffer, output[i], data_len[i] ) ) { printf( "failed!/n" ); return( 1 ); } printf( "passed./n" ); } printf( "/n" ); return( 0 ); } #endif
=========
comment*
Algorithm: RC4 ( Stream Cipher )
Usage: invokerc4_setkey,addr ptrInkey,addr ptrInkey_length
invokerc4_crypt,addr ptrIndata,addr ptrIndata_length( Encrypt & Decrypt )
Coded by x3chun(2003.11.22)
(x3chun@korea.com or x3chun@hanyang.ac.kr) ( http://x3chun.wo.to )
comment*
rc4_setkeyproto:DWORD, :DWORD
rc4_cryptproto:DWORD, :DWORD
.data?
rc4keytabledb256dup(?)
.code
rc4_setkeyprocptrInkey:DWORD, ptrInkey_length:DWORD
xorebx,ebx
@_r1:
mov[rc4keytable+ebx],bl
incebx
cmpebx,256
jnz@_r1
movesi,ptrInkey
xoreax,eax
xorebx,ebx
xorecx,ecx
xoredi,edi
@_r3:
moval,[rc4keytable+ecx]
addbl,byte ptr [esi+edi]
addbl,al
movdl,[rc4keytable+ebx]
mov[rc4keytable+ecx],dl
mov[rc4keytable+ebx],al
incedi
cmpedi,ptrInkey_length
jl@_r2
xoredi,edi
@_r2:
incecx
cmpecx,256
jnz@_r3
ret
rc4_setkeyendp
rc4_cryptprocptrIndata:DWORD, ptrIndata_length:DWORD
xoreax,eax
xorebx,ebx
xoredi,edi
xoredx,edx
movesi,ptrIndata
@_r1:
movcl,[rc4keytable+1+eax]
adddl,cl
movbl,[rc4keytable+edx]
mov[rc4keytable+edx],cl
addbl,cl
movbl,[rc4keytable+ebx]
xor[esi+edi],bl
inceax
incedi
cmpptrIndata_length,edi
jnz@_r1
ret
rc4_cryptendp
===============
标准RC4源代码(C)
/* rc4.h */ JVBCyZ@
typedef struct rc4_key E>j]@'pew
{ [Dpb<|
unsigned char state[256]; c0D]0/
unsigned char x; -6mZfx
unsigned char y; g1QT@ 1P|?
} rc4_key; `3R)6XJ>
void prepare_key(unsigned char *key_data_ptr,int key_data_len, 0^ ,R=O 1
rc4_key *key); =9_'?wn[*
void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key); ;8Y{ Pc
/*rc4.c */ 9g,_w*F
#include "rc4.h" =?vvz5H8
43u 7 /#.i
static void swap_byte(unsigned char *a, unsigned char *b); Y&)7[C
3R]";r2Yi
void prepare_key(unsigned char *key_data_ptr, int key_data_len, :t=:/ZW
rc4_key *key) Dj=l?G@
{ I=3Cp
unsigned char swapByte; D2Bi.l>/w
unsigned char index1; -?xj.
unsigned char index2; N+N<bS3
unsigned char* state; W#uC2T:
short counter; I&uRgUb
/X/~VU-?C
state = &key->state[0]; d:QA9F
for(counter = 0; counter < 256; counter++) eXfW o^Bxd
state[counter] = counter; qb7AT)U!
key->x = 0; Uu 7zb|
key->y = 0; -44p,T]u
index1 = 0; n |KN
index2 = 0; muc;{Snc
for(counter = 0; counter < 256; counter++) x+ jPs_
{ fTV=[|>O6
index2 = (key_data_ptr[index1] + state[counter] + V8r 0C~;]
index2) % 256; bU~Fe=r
swap_byte(&state[counter], &state[index2]); 0FS%DPdML
* &nhJvki
index1 = (index1 + 1) % key_data_len; e%JV `.6v
} r'k<5w
} $kOu yd
pt{AB
void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) d#n} AWu
{ G~ZH2H,;f
unsigned char x; P4HK74Q
unsigned char y; <ZsAv7H$
unsigned char* state; w+8h!/I
unsigned char xorIndex; "?AK(LE
short counter; MA[+?5kp
Y` >yu/8
x = key->x; gE0s Y1^
y = key->y; PF7MDY
0=dR|9
state = &key->state[0]; JpE' Os"
for(counter = 0; counter < buffer_len; counter ++) k3"$ P{A,
{ ??5x#2
x = (x + 1) % 256; <sW1J7GK
y = (state[x] + y) % 256; Vz p0[8
swap_byte(&state[x], &state[y]); 1:N ?SE
s;FFO(ko
xorIndex = (state[x] + state[y]) % 256; tz2Z4{c
>Dm;Tj^9!
buffer_ptr[counter] ^= state[xorIndex]; Q(YM6L
} q%
key->x = x; +#YC.LaT
key->y = y; }:DF4d0>
} /+MG
+a v{Y
static void swap_byte(unsigned char *a, unsigned char *b) li~gW2
{ 2TP&5| ,W
unsigned char swapByte; 35!cyiqG0'
(+rXR%.Lx
swapByte = *a; "3&?I:
*a = *b; 9M C/&2?
*b = swapByte; cEG[g
}
=============================
#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;
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;
}
int main()
{
char seed[256]; //key in fact
char data[512];
char fname[512];
char *tn;
char buf[buf_size];
char digit[5];
int hex, rd,i;
int n;
rc4_key key;
FILE *fp,*des;
memset(fname,0,512*sizeof(char));
if((fp=fopen("key.txt","r"))==NULL)
exit(1);
fscanf(fp,"%s %s",data,fname);
fclose(fp);
if(strcmp(fname,"")==0)
{
fprintf(stderr,"can't find the name of the file for encryption./n");
return 1;
}
n = strlen(data);
if(n>512)
{
fprintf(stderr,"can't tolerate key longer than 512 characters./n");
return 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);
if((fp=fopen(fname,"r"))==NULL)
exit(1);
tn=strdup(fname);
strcat(fname,".en");
if((des=fopen(fname,"w"))==NULL)
exit(1);
rd = fread(buf,1,buf_size,fp);
while (rd>0)
{
rc4(buf,rd,&key);
fwrite(buf,1,rd,des);
rd = fread(buf,1,buf_size,fp);
}
fclose(fp);
fclose(des);
sprintf(fname,"rm %s",tn);
system(fname);
sprintf(fname,"mv %s.en %s",tn,tn);
system(fname);
}
旁注:
1. 此代码是在UNIX下编写调试的,其中用到了函数system()来调用系统命令,所以要在windows下运行可能需要一些修改。
2. 运行该代码需要先创建文件key.txt,文件格式如下:
key filename
本文地址:http://www.45fan.com/dnjc/72843.html