对称加解密算法RC4原理过程及实现
zsk Lv4

介绍

RC4是一种流密码,可实现短密钥到长密钥的转换,流密码的加密就是比特的异或,为了安全性,关键就是密钥的生成,RC4就是解决密钥生成问题的。

流密码结构:
image


流密码类似于”一次一密”,不同的是”一次一密”使用的是真正的随机数流,而流密码使用的是伪随机数流。

设计流密码的主要因素

1、加密序列的周期要长,若出现重复的周期过短,容易被破解

2、密钥流应该尽可能地接近真正随机数流的特征

3、密钥长度要长,以避免琼穷举攻击

image


步骤

1. 密钥编排,向量S和Y初始化

RC4的实现需要三个向量,初始向量S,密钥K,临时向量T

初始化向量S和T,将向量S填充为0到255的数值,根据密钥K,填充向量T。如果密钥K

比向量S短,就依次重复填充密钥K,如果与向量S等长,那么向量T与密钥K相同。

1
2
3
4
5
6
S = []  # 状态数组
T = [] # 临时数组
# 初始化S和T
for i in range(256):
S.append(i)
T.append(key[i % len(key)])

2. 向量S的初始置换,将原来有序的向量S重新排列

从0遍历到255,每次 j=(j+S[i]+ord(T[i]))%256,然后交换S[i] 和 S[j],这样S盒顺序就被打乱了

1
2
3
4
5
6
# 用T产生S的初始置换
j = 0
for i in range(256):
j = (j + S[i] + ord(T[i])) % 256
S[i], S[j] = S[j], S[i] # 交换S[i] 和 S[j]
# print(S)

3. 密钥生成,每加密一个字符,就需要生成一个字节的密钥

根据明文长度生成密钥流

1
2
3
4
5
6
7
8
Ks = []
i = j = 0
for _ in range(len(M)):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
Ks.append(t)

4. 循环明文长度,每一个字符跟向量S异或

1
2
3
4
C = ""
for i in range(len(M)):
C += chr(ord(M[i]) ^ S[Ks[i]])
return C

解密也就是把密文当成明文再把加密执行一次

代码

python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 密钥编排函数
def KSA(key):
S = [] # 状态数组
T = [] # 临时数组
# 初始化S和T
for i in range(256):
S.append(i)
T.append(key[i % len(key)])
# print(S)
# print(T)

# 用T产生S的初始置换
j = 0
for i in range(256):
j = (j + S[i] + ord(T[i])) % 256
S[i], S[j] = S[j], S[i] # 交换S[i] 和 S[j]
# print(S)
# print(T)
return S

# 密钥流生成函数
def generateKey(S, M):
Ks = []
i = j = 0
for _ in range(len(M)):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
Ks.append(t)
return Ks

# 加密函数
def Rc4_encode(M, key):
C = ""
S = KSA(key) # 密钥编排
Ks = generateKey(S, M)
for i in range(len(M)):
C += chr(ord(M[i]) ^ S[Ks[i]])
return C

# 解密函数
def Rc4_decode(C, key):
M = ""
S = KSA(key) # 密钥编排
Ks = generateKey(S, C)
for i in range(len(C)):
M += chr(ord(C[i]) ^ S[Ks[i]])
return M

key = '123456789'
m = 'hello'

C = Rc4_encode(m, key)
print("加密后密文:", C)

M = Rc4_decode(C, key)
print("解密后明文:", M)

c++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <cstring>

using namespace std;

void rc4_init(unsigned char *S, char *key, int key_len) {
unsigned char T[256] = {0};
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % key_len];
}
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
swap(S[i], S[j]);
}
}

void rc4_crypto(unsigned char *S, char *text, int text_len) {
int i = 0, j = 0, t = 0;
for (int k = 0; k < text_len; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(S[i], S[j]);
t = (S[i] + S[j]) % 256;
text[k] ^= S[t];
}
}


string rc4_main(char *text, int text_len, char *key) {

int key_len = sizeof key - 1;
unsigned char S[256] = {0};

rc4_init(S, key, key_len);
rc4_crypto(S, text, text_len);

printf("result => %s\n", text);

// char out[100] = {0};
// base64_encode(text,out);
// printf("result(base64) => %s", out);
return text;
}

int main() {
char key[] = "12345";
char text[] = "hello";
int text_len = sizeof(text) - 1;
string aa = rc4_main(text, text_len, key);
cout<<aa<<endl;
return 0;
}
 评论