现在的位置: 首页 > 综合 > 正文

RC4 加密

2013年04月05日 ⁄ 综合 ⁄ 共 8059字 ⁄ 字号 评论关闭
#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  : invoke rc4_setkey,addr ptrInkey,addr ptrInkey_length
    invoke rc4_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_setkey proto :DWORD, :DWORD
rc4_crypt proto :DWORD, :DWORD

.data?

rc4keytable db 256 dup(?)

.code

rc4_setkey proc ptrInkey:DWORD, ptrInkey_length:DWORD

  xor ebx,ebx  
@_r1:
  mov [rc4keytable+ebx],bl
  inc ebx
  cmp ebx,256
  jnz @_r1
  
  mov esi,ptrInkey
  xor eax,eax
  xor ebx,ebx  
  xor ecx,ecx  
  xor edi,edi  
@_r3:
  mov al,[rc4keytable+ecx]
  add bl,byte ptr [esi+edi]
  add bl,al  
  mov dl,[rc4keytable+ebx]
  mov [rc4keytable+ecx],dl
  mov [rc4keytable+ebx],al
  inc edi
  cmp edi,ptrInkey_length
  jl @_r2
  xor edi,edi
@_r2:
  inc ecx
  cmp ecx,256
  jnz @_r3 
  ret
  
rc4_setkey endp

rc4_crypt proc ptrIndata:DWORD, ptrIndata_length:DWORD

  xor eax,eax
  xor ebx,ebx
  xor edi,edi
  xor edx,edx
  mov esi,ptrIndata
@_r1: 
  mov cl,[rc4keytable+1+eax] 
  add dl,cl
  mov bl,[rc4keytable+edx] 
  mov [rc4keytable+edx],cl
  add bl,cl
  mov bl,[rc4keytable+ebx]
  xor [esi+edi],bl
  inc eax
  inc edi 
  cmp ptrIndata_length,edi
  jnz @_r1 
  ret
  
rc4_crypt endp

===============

标准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

抱歉!评论已关闭.