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次,保证每个字节都得到处理

  解密:把密钥流重新拿过来异或一次就能得到原文。

   密文数据的长度正好是明文数据长度的两倍。

注意:

  网页上的加解密可能是加盐的,比如该网页:在线RC4加密 | RC4解密- 在线工具 (sojson.com)      

  例如:明文AB54425D,1670334432,0  密钥:To7QG3yWupCfcWNWcMSbWWpnmFJDSlWWqUsArPwH16gaagsK   密文:U2FsdGVkX187INtjwgSpj27WtcyeCbgOjdBhBGHuCv1/5wx4Tw==

      

 

 

  但是,这个密文数据在如下代码下是解密不出来的,因为该网页的RC4加解密有盐值,不知道该加解密盐值的话不能解密。这个密文数据通过如下RC4算法是不能解密的。

 

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 }

 

 

 

posted @ 2021-12-29 09:52  耿通宇  阅读(1135)  评论(0编辑  收藏  举报