天天看點

RC4加解密

RC4:對稱加密算法(加解密使用同一個密鑰)。

特點:算法簡單,運作速度快,密鑰長度可變(範圍1-256位元組)。

原理:1.初始化密匙盒子。

   2.僞随機密碼生成。 

          1、先初始化狀态向量rc_key(256個位元組,用來作為密鑰流生成的種子1)

              按照升序,給每個位元組指派0,1,2,3,4,5,6…..,254,255

  2、初始密鑰(由使用者輸入),長度任意

  如果輸入長度小于256個位元組,則進行輪轉,直到填滿

  例如輸入密鑰的是1,2,3,4,5 , 那麼填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5……..

  由上述輪轉過程得到256個位元組的向量T(用來作為密鑰流生成的種子2)

  3、開始對狀态向量S進行置換操作(用來打亂初始種子1)

  按照下列規則進行

  從第零個位元組開始,執行256次,保證每個位元組都得到處理

  解密:把密鑰流重新拿過來異或一次就能得到原文。

C語言代碼如下:

1 #include "stdio.h"
  2 #include "string.h"
  3 void rc4_set_key(unsigned char* rc_key, unsigned char* key, int keylen);
  4 void rc4_transform(unsigned char* rc_key, unsigned char* input, int len);
  5 void asc_hex(unsigned char* asc_buf, unsigned char* hex_buf, unsigned int length);
  6 void hex_asc(unsigned char* hex_buf, unsigned char* asc_buf, unsigned short length);
  7 
  8 char key_buf[] = {"TONGYU123456@#"};
  9 unsigned char str_buf1[300];
 10 unsigned char s2[300];
 11 char In_data[300] = {"[18487118765,,20211008103230,,,]"}; 
 12 char out_data[300]={0}; 
 13 
 14 int main(void)
 15 {
 16     char tmp_buff_A[100];     
 17     short keylen,In_len,i;    
 18         keylen = strlen("TONGYU123456@#");
 19         In_len = strlen("[18487118765,,20211008103230,,,]");    
 20 /********************RC4加密 ***************************/     
 21     rc4_set_key(str_buf1,key_buf,keylen);               
 22     rc4_transform(str_buf1,(char *)In_data,In_len);
 23     printf("In_data轉化前:%x\n",In_data[0]);        //加密後是一堆16進制資料  
 24     hex_asc(In_data, tmp_buff_A,In_len);           //将加密的16進制資料轉化為ASCII碼 ----友善顯示 
 25     In_len = In_len*2;
 26     memcpy(In_data,tmp_buff_A,In_len);
 27     printf("In_data十六進制轉ASCII:%s\n",In_data);//In_data:7B66237D3006EC0791E40F241220F2A8A003A226356299DBEE972E2E193E3A5C
 28 
 29 /********************RC4解密 ***************************/ 
 30     asc_hex((char *)In_data,tmp_buff_A,In_len);    //加解密的資料必須保持一緻,加密後是16進制,是以解密也要用16進制      
 31     In_len = In_len/2;
 32     memcpy(In_data,tmp_buff_A,In_len);                
 33     rc4_set_key(str_buf1,key_buf,keylen);  
 34     rc4_transform(str_buf1,(char *)In_data,In_len);
 35     printf("In_data解密:%s\n",In_data); //In_data:[18487118765,,20211008103230,,,]A003A226356299DBEE972E2E193E3A5C 
 36 return 0;
 37 }
 38 
 39 void rc4_set_key(unsigned char* rc_key, unsigned char* key, int keylen)  
 40 {  
 41     int i = 0, j = 0;
 42     unsigned char tmp;
 43     for (i = 0; i < 256; i++)  
 44     {  
 45         rc_key[i] = i;  
 46     }  
 47     for (i = 0; i < 256; i++)  
 48     {  
 49             j = (j + rc_key[i] + key[i % keylen]) % 256;  
 50             tmp = rc_key[i];
 51             rc_key[i] = rc_key[j];
 52             rc_key[j] = tmp;  
 53     }  
 54 }  
 55 
 56 void rc4_transform(unsigned char* rc_key, unsigned char* input, int len)  
 57 {  
 58     int i = 0, j = 0, k = 0;
 59     char tmp;
 60     unsigned char subkey;    
 61     for (k = 0; k < len; k++)  
 62     {  
 63         i = (i + 1) % 256;  
 64         j = (j + rc_key[i]) % 256;  
 65         
 66                 tmp = rc_key[i];
 67                 rc_key[i] = rc_key[j];
 68                 rc_key[j] = tmp;  
 69         subkey = rc_key[(rc_key[i] + rc_key[j]) % 256];  
 70         input[k] ^= subkey;      
 71     }  
 72 }
 73 //ASCII碼轉換為16進制  
 74 void asc_hex(unsigned char* asc_buf, unsigned char* hex_buf, unsigned int length)
 75 {
 76     int i,j;
 77     for (i = 0, j = 0; i < length ; i++)
 78     {
 79         if (asc_buf[i] > '9')
 80         {
 81             hex_buf[j] = 9 + (asc_buf[i] & 0x0F);
 82         }
 83         else
 84         {
 85             hex_buf[j] = asc_buf[i] & 0x0F;
 86         }
 87 
 88         hex_buf[j] <<= 4;
 89         i++;
 90         if (asc_buf[i] > '9')
 91         {
 92             hex_buf[j] |= 9 + (asc_buf[i] & 0x0F);
 93         }
 94         else
 95         {
 96             hex_buf[j] |= asc_buf[i] & 0x0F;
 97         }
 98         j++;
 99     }
100 }
101 //16進制轉換為ASCII碼
102 void hex_asc(unsigned char* hex_buf, unsigned char* asc_buf, unsigned short length)
103 {
104     unsigned short i;
105     unsigned char byte;
106     for (i = 0; i < length; i++)
107     {
108         byte = hex_buf[i] >> 4;
109         if (byte > 9)
110         {
111             asc_buf[i*2] = 'A' + byte - 10;
112         }
113         else
114         {
115             asc_buf[i*2] = '0' + byte;
116         }
117 
118         byte = hex_buf[i] & 0x0F;
119         if (byte > 9)
120         {
121             asc_buf[i*2+1] = 'A' + byte - 10;
122         }
123         else
124         {
125             asc_buf[i*2+1] = '0' + byte;
126         }
127     }
128 }