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 }